Module adcp.types.domains.core

Types the AdCP core 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.core 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.core.<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.core.acceptance_policy_profile_ids
adcp.types.domains.core.account
adcp.types.domains.core.account_authorization
adcp.types.domains.core.account_change
adcp.types.domains.core.account_change_recorded_webhook
adcp.types.domains.core.account_identity_change
adcp.types.domains.core.account_identity_change_preview
adcp.types.domains.core.account_ref
adcp.types.domains.core.account_status_changed_webhook
adcp.types.domains.core.account_timezone_capability
adcp.types.domains.core.account_with_authorization
adcp.types.domains.core.activation_key
adcp.types.domains.core.ad_inventory_config
adcp.types.domains.core.agent_encryption_key
adcp.types.domains.core.agent_notification_config
adcp.types.domains.core.agent_notification_config_state
adcp.types.domains.core.agent_reporting_destination
adcp.types.domains.core.agent_reporting_destination_state
adcp.types.domains.core.agent_signing_key
adcp.types.domains.core.agent_webhook_challenge
adcp.types.domains.core.app_item
adcp.types.domains.core.applicable_package_id
adcp.types.domains.core.asset_group_vocabulary
adcp.types.domains.core.assets
adcp.types.domains.core.async_response_data
adcp.types.domains.core.async_response_refs
adcp.types.domains.core.attestation_capabilities
adcp.types.domains.core.attestation_evaluation
adcp.types.domains.core.attestation_issuer
adcp.types.domains.core.attestation_reference
adcp.types.domains.core.attestation_subject
adcp.types.domains.core.attribution_window
adcp.types.domains.core.audience_activation_method
adcp.types.domains.core.audience_characteristic
adcp.types.domains.core.audience_evidence
adcp.types.domains.core.audience_evidence_pin
adcp.types.domains.core.audience_evidence_requirements
adcp.types.domains.core.audience_evidence_selection
adcp.types.domains.core.audience_member
adcp.types.domains.core.audience_selector
adcp.types.domains.core.audience_source
adcp.types.domains.core.authorized_agent_base
adcp.types.domains.core.bidding_policy
adcp.types.domains.core.bidding_policy_capability
adcp.types.domains.core.brand_id
adcp.types.domains.core.brand_key
adcp.types.domains.core.brand_ref
adcp.types.domains.core.brand_response_authorization_result
adcp.types.domains.core.budget_allocation
adcp.types.domains.core.budget_range
adcp.types.domains.core.business_entity
adcp.types.domains.core.cancellation_policy
adcp.types.domains.core.canonical_account_ref
adcp.types.domains.core.canonical_audience_evidence
adcp.types.domains.core.canonical_audience_evidence_selection
adcp.types.domains.core.canonical_budget_allocation
adcp.types.domains.core.canonical_delivery_forecast
adcp.types.domains.core.canonical_forecast_point
adcp.types.domains.core.canonical_forecast_vendor_metric_value
adcp.types.domains.core.canonical_format_kind
adcp.types.domains.core.canonical_format_option
adcp.types.domains.core.canonical_measurement_terms
adcp.types.domains.core.canonical_media_buy_action
adcp.types.domains.core.canonical_media_buy_action_fields
adcp.types.domains.core.canonical_media_buy_features
adcp.types.domains.core.canonical_metric_qualifier
adcp.types.domains.core.canonical_optimization_goal
adcp.types.domains.core.canonical_performance_standard
adcp.types.domains.core.canonical_placement
adcp.types.domains.core.canonical_pricing_option
adcp.types.domains.core.canonical_product
adcp.types.domains.core.canonical_product_action
adcp.types.domains.core.canonical_projection_ref
adcp.types.domains.core.canonical_projection_slot_override
adcp.types.domains.core.canonical_proposal
adcp.types.domains.core.canonical_reporting_capabilities
adcp.types.domains.core.canonical_reporting_commitment
adcp.types.domains.core.canvas_constraint
adcp.types.domains.core.capabilities_changed_webhook
adcp.types.domains.core.catalog
adcp.types.domains.core.catalog_field_mapping
adcp.types.domains.core.catalog_item_availability_error
adcp.types.domains.core.catalog_item_availability_ref
adcp.types.domains.core.catalog_item_availability_state
adcp.types.domains.core.catalog_item_availability_update
adcp.types.domains.core.catalog_item_availability_update_result
adcp.types.domains.core.catalog_item_delivery_metrics
adcp.types.domains.core.catalog_item_reference_not_found_error
adcp.types.domains.core.catalog_selection
adcp.types.domains.core.catchment
adcp.types.domains.core.collection
adcp.types.domains.core.collection_delivery_metrics
adcp.types.domains.core.collection_distribution
adcp.types.domains.core.collection_list_ref
adcp.types.domains.core.collection_property_delivery_metrics
adcp.types.domains.core.collection_ref
adcp.types.domains.core.collection_selection
adcp.types.domains.core.collection_selector
adcp.types.domains.core.committed_metric
adcp.types.domains.core.compact_task_input_required
adcp.types.domains.core.compact_task_submitted
adcp.types.domains.core.compact_task_working
adcp.types.domains.core.content_rating
adcp.types.domains.core.context
adcp.types.domains.core.creative_approval_scope
adcp.types.domains.core.creative_asset
adcp.types.domains.core.creative_assets
adcp.types.domains.core.creative_assignment
adcp.types.domains.core.creative_brief
adcp.types.domains.core.creative_consumption
adcp.types.domains.core.creative_delivery_metrics
adcp.types.domains.core.creative_filters
adcp.types.domains.core.creative_item
adcp.types.domains.core.creative_locale_policy
adcp.types.domains.core.creative_localization
adcp.types.domains.core.creative_localization_readback
adcp.types.domains.core.creative_manifest
adcp.types.domains.core.creative_operation_format_declaration
adcp.types.domains.core.creative_policy
adcp.types.domains.core.creative_representation
adcp.types.domains.core.creative_representation_set
adcp.types.domains.core.creative_revision_id
adcp.types.domains.core.creative_variable
adcp.types.domains.core.creative_variant
adcp.types.domains.core.daast_tracker_constraints
adcp.types.domains.core.data_provider_signal_selector
adcp.types.domains.core.date_range
adcp.types.domains.core.datetime_range
adcp.types.domains.core.daypart_target
adcp.types.domains.core.deadline_policy
adcp.types.domains.core.delivery_breakdown_controls
adcp.types.domains.core.delivery_forecast
adcp.types.domains.core.delivery_metric_aggregate
adcp.types.domains.core.delivery_metrics
adcp.types.domains.core.delivery_provider
adcp.types.domains.core.delivery_recipient
adcp.types.domains.core.demographic_age_range
adcp.types.domains.core.demographic_predicate
adcp.types.domains.core.demographic_reporting_capability
adcp.types.domains.core.demographic_targeting_capability
adcp.types.domains.core.demographic_targeting_intent
adcp.types.domains.core.demographic_targeting_resolution
adcp.types.domains.core.deployment
adcp.types.domains.core.destination
adcp.types.domains.core.destination_item
adcp.types.domains.core.diagnostic_issue
adcp.types.domains.core.downstream_connection_requirement
adcp.types.domains.core.duration
adcp.types.domains.core.education_item
adcp.types.domains.core.error
adcp.types.domains.core.evaluator_spec
adcp.types.domains.core.event
adcp.types.domains.core.event_custom_data
adcp.types.domains.core.event_source_health
adcp.types.domains.core.event_surface
adcp.types.domains.core.experimental_feature_id
adcp.types.domains.core.ext
adcp.types.domains.core.feature_requirement
adcp.types.domains.core.flight_item
adcp.types.domains.core.forecast_dimension_audience
adcp.types.domains.core.forecast_dimension_device_platform
adcp.types.domains.core.forecast_dimension_device_type
adcp.types.domains.core.forecast_dimension_geo
adcp.types.domains.core.forecast_dimension_placement
adcp.types.domains.core.forecast_dimension_signal
adcp.types.domains.core.forecast_dimension_time
adcp.types.domains.core.forecast_point
adcp.types.domains.core.forecast_point_dimensions
adcp.types.domains.core.forecast_range
adcp.types.domains.core.forecast_rate_range
adcp.types.domains.core.forecast_vendor_metric_value
adcp.types.domains.core.format
adcp.types.domains.core.format_id
adcp.types.domains.core.format_option_ref
adcp.types.domains.core.format_shape_vocabulary
adcp.types.domains.core.frequency_cap
adcp.types.domains.core.frequency_cap_constraints
adcp.types.domains.core.frequency_cap_duration_unit
adcp.types.domains.core.frequency_cap_impression_constraints
adcp.types.domains.core.frequency_cap_interval_constraints
adcp.types.domains.core.frequency_cap_requirements
adcp.types.domains.core.generation_credential
adcp.types.domains.core.geo_breakdown_support
adcp.types.domains.core.geo_delivery_metrics
adcp.types.domains.core.geo_metro
adcp.types.domains.core.geo_place_area
adcp.types.domains.core.geo_place_catalog_capability
adcp.types.domains.core.geo_place_catalog_entry
adcp.types.domains.core.geo_place_requirement
adcp.types.domains.core.geo_place_resolver
adcp.types.domains.core.geo_place_support
adcp.types.domains.core.geo_place_system
adcp.types.domains.core.geo_place_type
adcp.types.domains.core.geo_region_requirement
adcp.types.domains.core.geo_region_support
adcp.types.domains.core.get_geo_place_resolution_request
adcp.types.domains.core.get_geo_place_resolution_response
adcp.types.domains.core.hotel_item
adcp.types.domains.core.iana_timezone
adcp.types.domains.core.identifier
adcp.types.domains.core.impairment
adcp.types.domains.core.indicator
adcp.types.domains.core.indicator_bearing
adcp.types.domains.core.indicator_scope
adcp.types.domains.core.indicators_changed_webhook
adcp.types.domains.core.industry_identifier
adcp.types.domains.core.insertion_order
adcp.types.domains.core.installment
adcp.types.domains.core.installment_deadlines
adcp.types.domains.core.installment_delivery_metrics
adcp.types.domains.core.installment_property_delivery_metrics
adcp.types.domains.core.installment_ref
adcp.types.domains.core.inventory_list_application
adcp.types.domains.core.job_item
adcp.types.domains.core.keyword_delivery_metrics
adcp.types.domains.core.keyword_target
adcp.types.domains.core.limited_series
adcp.types.domains.core.locale_tag
adcp.types.domains.core.localized_creative_asset
adcp.types.domains.core.macro_bearing_url
adcp.types.domains.core.macro_declaration
adcp.types.domains.core.macro_encoding
adcp.types.domains.core.macro_resolution_capability
adcp.types.domains.core.macro_resolution_result
adcp.types.domains.core.macro_translation_target
adcp.types.domains.core.material_deadline
adcp.types.domains.core.mcp_webhook_payload
adcp.types.domains.core.measurement_readiness
adcp.types.domains.core.measurement_terms
adcp.types.domains.core.measurement_window
adcp.types.domains.core.media_buy
adcp.types.domains.core.media_buy_available_action
adcp.types.domains.core.media_buy_available_action_id
adcp.types.domains.core.media_buy_change_term_id
adcp.types.domains.core.media_buy_features
adcp.types.domains.core.media_buy_frequency_cap
adcp.types.domains.core.media_buy_frequency_cap_capability
adcp.types.domains.core.media_buy_frequency_cap_requirement
adcp.types.domains.core.media_buy_frequency_cap_support
adcp.types.domains.core.media_buy_legacy_terms_ref
adcp.types.domains.core.media_buy_support
adcp.types.domains.core.media_buy_support_requirements
adcp.types.domains.core.missing_metric
adcp.types.domains.core.negative_keyword
adcp.types.domains.core.notification_config
adcp.types.domains.core.offering
adcp.types.domains.core.offering_asset_group
adcp.types.domains.core.operator_identity
adcp.types.domains.core.operator_unit
adcp.types.domains.core.opportunity_context
adcp.types.domains.core.optimization_goal
adcp.types.domains.core.outcome_measurement
adcp.types.domains.core.outcome_target_cost_per
adcp.types.domains.core.overlay
adcp.types.domains.core.package
adcp.types.domains.core.package_delivery_metric_value
adcp.types.domains.core.package_format_snapshot
adcp.types.domains.core.package_signal_targeting
adcp.types.domains.core.package_signal_targeting_group
adcp.types.domains.core.package_signal_targeting_groups
adcp.types.domains.core.package_targeting_resolution
adcp.types.domains.core.pagination_request
adcp.types.domains.core.pagination_response
adcp.types.domains.core.performance_feedback
adcp.types.domains.core.performance_feedback_assertion
adcp.types.domains.core.performance_feedback_metric
adcp.types.domains.core.performance_standard
adcp.types.domains.core.placement
adcp.types.domains.core.placement_definition
adcp.types.domains.core.placement_delivery_metrics
adcp.types.domains.core.placement_evidence
adcp.types.domains.core.placement_identity
adcp.types.domains.core.placement_presentation
adcp.types.domains.core.placement_property_delivery_metrics
adcp.types.domains.core.placement_ref
adcp.types.domains.core.placement_selection
adcp.types.domains.core.planned_delivery
adcp.types.domains.core.platform_extension_ref
adcp.types.domains.core.positive_postal_area_support
adcp.types.domains.core.postal_area
adcp.types.domains.core.postal_area_support
adcp.types.domains.core.postal_country_system
adcp.types.domains.core.presentation_ref
adcp.types.domains.core.preview_provider
adcp.types.domains.core.preview_renderer_metadata
adcp.types.domains.core.price
adcp.types.domains.core.pricing_option
adcp.types.domains.core.principal_changed_webhook
adcp.types.domains.core.principal_declarations
adcp.types.domains.core.principal_declarations_state
adcp.types.domains.core.principal_state
adcp.types.domains.core.product
adcp.types.domains.core.product_allocation
adcp.types.domains.core.product_allowed_action
adcp.types.domains.core.product_audience_evidence_requirements
adcp.types.domains.core.product_card_reference_asset
adcp.types.domains.core.product_change_map
adcp.types.domains.core.product_execution_requirement
adcp.types.domains.core.product_filters
adcp.types.domains.core.product_format_declaration
adcp.types.domains.core.product_identity
adcp.types.domains.core.product_offer_filters
adcp.types.domains.core.product_signal_targeting_option
adcp.types.domains.core.product_targeting_resolution
adcp.types.domains.core.property
adcp.types.domains.core.property_delivery_metrics
adcp.types.domains.core.property_id
adcp.types.domains.core.property_list_ref
adcp.types.domains.core.property_ref
adcp.types.domains.core.property_tag
adcp.types.domains.core.proposal
adcp.types.domains.core.protocol_envelope
adcp.types.domains.core.provenance
adcp.types.domains.core.publisher_property_selector
adcp.types.domains.core.push_notification_config
adcp.types.domains.core.real_estate_item
adcp.types.domains.core.reference_asset
adcp.types.domains.core.reference_renderer
adcp.types.domains.core.registry_event
adcp.types.domains.core.registry_feed_response
adcp.types.domains.core.reporting_adjustment
adcp.types.domains.core.reporting_adjustment_receipt
adcp.types.domains.core.reporting_canonical_content_digest
adcp.types.domains.core.reporting_canonicalization_contract
adcp.types.domains.core.reporting_capabilities
adcp.types.domains.core.reporting_consumer_status
adcp.types.domains.core.reporting_control_total
adcp.types.domains.core.reporting_coverage
adcp.types.domains.core.reporting_dataset_share_destination
adcp.types.domains.core.reporting_delivery_capabilities
adcp.types.domains.core.reporting_delivery_config
adcp.types.domains.core.reporting_delivery_config_state
adcp.types.domains.core.reporting_delivery_method
adcp.types.domains.core.reporting_delivery_offering
adcp.types.domains.core.reporting_delivery_offering_id
adcp.types.domains.core.reporting_delivery_ready_webhook
adcp.types.domains.core.reporting_file_compression
adcp.types.domains.core.reporting_file_entry
adcp.types.domains.core.reporting_file_manifest
adcp.types.domains.core.reporting_file_object_ref
adcp.types.domains.core.reporting_ledger_changed_webhook
adcp.types.domains.core.reporting_materialization
adcp.types.domains.core.reporting_native_version_ref
adcp.types.domains.core.reporting_obligation
adcp.types.domains.core.reporting_receipt
adcp.types.domains.core.reporting_reconciliation_mode
adcp.types.domains.core.reporting_reliability_statistics
adcp.types.domains.core.reporting_report_definition
adcp.types.domains.core.reporting_resource
adcp.types.domains.core.reporting_revision
adcp.types.domains.core.reporting_schedule
adcp.types.domains.core.reporting_schedule_offering
adcp.types.domains.core.reporting_status_changed_webhook
adcp.types.domains.core.reporting_status_issue
adcp.types.domains.core.reporting_verification
adcp.types.domains.core.reporting_verification_profile
adcp.types.domains.core.reporting_verification_profile_set
adcp.types.domains.core.reporting_webhook
adcp.types.domains.core.reporting_write_destination
adcp.types.domains.core.representation_destination
adcp.types.domains.core.representation_rejection
adcp.types.domains.core.representation_selection
adcp.types.domains.core.requirements
adcp.types.domains.core.response
adcp.types.domains.core.response_payload_jws_envelope
adcp.types.domains.core.rights_attestation_evaluation
adcp.types.domains.core.rights_constraint
adcp.types.domains.core.seller_agent_ref
adcp.types.domains.core.signal_coverage_forecast
adcp.types.domains.core.signal_definition
adcp.types.domains.core.signal_definition_enrichment
adcp.types.domains.core.signal_filters
adcp.types.domains.core.signal_id
adcp.types.domains.core.signal_listing
adcp.types.domains.core.signal_modeling_disclosure
adcp.types.domains.core.signal_pricing
adcp.types.domains.core.signal_pricing_option
adcp.types.domains.core.signal_ref
adcp.types.domains.core.signal_selection_group_rule
adcp.types.domains.core.signal_targeting
adcp.types.domains.core.signal_targeting_expression
adcp.types.domains.core.signal_targeting_rules
adcp.types.domains.core.sla_window
adcp.types.domains.core.special
adcp.types.domains.core.spot_reporting_capability
adcp.types.domains.core.start_timing
adcp.types.domains.core.store_item
adcp.types.domains.core.talent
adcp.types.domains.core.targeting
adcp.types.domains.core.targeting_input
adcp.types.domains.core.targeting_modification
adcp.types.domains.core.targeting_overlay_requirements
adcp.types.domains.core.targeting_overlay_support
adcp.types.domains.core.targeting_unknown_age_eligibility_constraint
adcp.types.domains.core.targeting_verified_age_basis_constraint
adcp.types.domains.core.tasks_get_request
adcp.types.domains.core.tasks_get_response
adcp.types.domains.core.tasks_list_request
adcp.types.domains.core.tasks_list_response
adcp.types.domains.core.tracker_execution_contract
adcp.types.domains.core.tracker_execution_selector
adcp.types.domains.core.transformer
adcp.types.domains.core.transformer_param
adcp.types.domains.core.truncation_sentinel
adcp.types.domains.core.user_match
adcp.types.domains.core.vast_media_file_requirements
adcp.types.domains.core.vast_tracker_constraints
adcp.types.domains.core.vehicle_item
adcp.types.domains.core.vendor_metric_id
adcp.types.domains.core.vendor_metric_optimization
adcp.types.domains.core.vendor_metric_optimization_supported_metric
adcp.types.domains.core.vendor_metric_value
adcp.types.domains.core.vendor_pricing_option
adcp.types.domains.core.verification_token_claims
adcp.types.domains.core.version_envelope
adcp.types.domains.core.warning
adcp.types.domains.core.warning_resource
adcp.types.domains.core.webhook_activity_record
adcp.types.domains.core.webhook_challenge
adcp.types.domains.core.webhook_challenge_response
adcp.types.domains.core.wholesale_feed_event
adcp.types.domains.core.wholesale_feed_webhook
adcp.types.domains.core.x_entity_types

Classes

class AcceptProposalInputRequired (**data: Any)
Expand source code
class AcceptProposalInputRequired(CompactTaskInputRequired):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class AcceptProposalSubmitted (**data: Any)
Expand source code
class AcceptProposalSubmitted(CompactTaskSubmitted):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class AcceptProposalWorking (**data: Any)
Expand source code
class AcceptProposalWorking(CompactTaskWorking):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class AcceptancePolicyProfileId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AcceptancePolicyProfileId(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class AcceptancePolicyProfileIds (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class AcceptancePolicyProfileIds(RootModel[list[AcceptancePolicyProfileId]]):
    root: Annotated[
        list[AcceptancePolicyProfileId],
        Field(
            description='Acceptance-policy profiles from the seller catalog that apply to this product in addition to seller defaults. Profiles compose restrictively; the most restrictive matching disposition wins.',
            min_length=1,
            title='Acceptance Policy Profile IDs',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[list[AcceptancePolicyProfileId]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[AcceptancePolicyProfileId]
class AcceptedAttestationIssuers1 (**data: Any)
Expand source code
class AcceptedAttestationIssuers1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['brand'] = 'brand'
    brand: brand_key.BrandKey
    ext: ext_1.ExtensionObject | 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 brand : BrandKey
var ext : ExtensionObject | None
var model_config
var type : Literal['brand']

Inherited members

class AcceptedAttestationIssuers2 (**data: Any)
Expand source code
class AcceptedAttestationIssuers2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['agent'] = 'agent'
    agent_url: AnyUrl
    ext: ext_1.ExtensionObject | 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 agent_url : pydantic.networks.AnyUrl
var ext : ExtensionObject | None
var model_config
var type : Literal['agent']

Inherited members

class AcceptedAttestationIssuers3 (**data: Any)
Expand source code
class AcceptedAttestationIssuers3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['origin'] = 'origin'
    origin: AnyUrl
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var model_config
var origin : pydantic.networks.AnyUrl
var type : Literal['origin']

Inherited members

class AcceptedFormat (*args, **kwds)
Expand source code
class AcceptedFormat(StrEnum):
    jsonl = 'jsonl'
    csv = 'csv'
    parquet = 'parquet'
    avro = 'avro'
    orc = 'orc'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var avro
var csv
var jsonl
var orc
var parquet
class AcceptedIssuer (**data: Any)
Expand source code
class AcceptedIssuer(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    issuer: attestation_issuer.AttestationIssuer
    claim_types: Annotated[
        list[AnyUrl] | None,
        Field(
            description='Optional subset of accepted_claim_types this issuer may assert. Omit to allow any globally accepted claim type for this issuer.',
            min_length=1,
        ),
    ] = None
    proof_formats: Annotated[
        list[AnyUrl] | None,
        Field(
            description='Optional subset of accepted_proof_formats allowed for this issuer. Omit to allow any globally accepted proof format for this issuer.',
            min_length=1,
        ),
    ] = None
    credential_origins: Annotated[
        list[CredentialOrigin] | None,
        Field(
            description='Canonical HTTPS origins from which credential_uri locators may be fetched for this issuer. Exact origin matching happens after URL canonicalization and before DNS resolution. Paths in the credential URI may vary; userinfo is forbidden.',
            min_length=1,
        ),
    ] = None
    resolvers: Annotated[
        list[Resolver] | None,
        Field(
            description='Evaluator-approved resolver endpoints for issuer_credential_id delivery. Presentations carry only resolver_id; they cannot replace url or authentication policy.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 claim_types : list[pydantic.networks.AnyUrl] | None
var credential_origins : list[CredentialOrigin] | None
var ext : ExtensionObject | None
var issuer : AttestationIssuer1 | AttestationIssuer2 | AttestationIssuer3
var model_config
var proof_formats : list[pydantic.networks.AnyUrl] | None
var resolvers : list[Resolver] | None

Inherited members

class Account (**data: Any)
Expand source code
class Account(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    account_id: Annotated[str, Field(description='Unique identifier for this account')]
    name: Annotated[
        str, Field(description="Human-readable account name (e.g., 'Acme', 'Acme c/o Pinnacle')")
    ]
    advertiser: Annotated[
        str | None, Field(description='The advertiser whose rates apply to this account')
    ] = None
    billing_proxy: Annotated[
        str | None,
        Field(
            description='Optional intermediary who receives invoices on behalf of the advertiser (e.g., agency)'
        ),
    ] = None
    status: Annotated[
        account_status.AccountStatus,
        Field(
            description='Account lifecycle status. See the Accounts Protocol overview for the operations matrix showing which tasks are permitted in each state.'
        ),
    ]
    brand: Annotated[
        brand_ref.BrandReference | None,
        Field(description='Brand reference identifying the advertiser'),
    ] = None
    operator: Annotated[
        str | None,
        Field(
            description="Domain of the entity operating this account. When the brand operates directly, this is the brand's domain.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    operator_unit: Annotated[
        operator_unit_1.OperatorUnit | None,
        Field(
            description='Operator-owned business unit, agency seat, or platform account associated with this advertiser account. The id round-trips from the natural key; name is mutable display metadata. This is distinct from account_id, which belongs to the seller/storefront namespace.'
        ),
    ] = None
    revision: Annotated[
        SchemaInt | None,
        Field(
            description='Monotonically increasing optimistic-concurrency token for this account. Incremented on every persisted settings change, identity-change request, and identity-change disposition; reads, dry runs, validation failures, and exact idempotency replays do not increment it. Pass the latest observed value in a sync_accounts settings-update entry to prevent lost updates.',
            ge=1,
        ),
    ] = None
    identity_change: Annotated[
        account_identity_change.AccountIdentityChange | None,
        Field(
            description='Pending or rejected operator-identity transition. While present, the top-level operator and operator_unit remain the current canonical identity. Re-read list_accounts until the request is applied (canonical fields change and this object disappears) or rejected.'
        ),
    ] = None
    currency: Annotated[
        str | None,
        Field(
            description="Immutable transaction currency when the seller's advertiser object is currency-bound. Media buys on this account MUST use this currency. Omit when the account selects currency independently per media buy.",
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    timezone: Annotated[
        str | None,
        Field(
            description='Immutable operational timezone for this account, expressed as UTC or an IANA timezone identifier. AdCP 3.2 sellers return it on every account. It is the default calendar-day boundary for account-scoped behavior unless a feature explicitly declares another timezone basis. For buyer-selected account_fixed provisioning it participates in the natural account key.',
            min_length=1,
        ),
    ] = None
    billing: Annotated[
        billing_party.BillingParty | None,
        Field(
            description="Who is invoiced on this account. See billing_entity for the invoiced party's business details."
        ),
    ] = None
    billing_entity: Annotated[
        business_entity.BusinessEntity | None,
        Field(
            description='Current canonical business entity for the party responsible for payment. Contains the legal name, tax IDs, and address needed for formal B2B invoicing. Corresponds to whoever billing points to (operator, agent, or advertiser). When this account appears in a response, bank details MUST be omitted and the request-only destination_billing_entity MUST NOT be exposed.'
        ),
    ] = None
    destination_billing_entity: Annotated[
        Any | None,
        Field(description='Request-only staging field. It MUST NOT appear in account read models.'),
    ] = None
    rate_card: Annotated[
        str | None, Field(description='Identifier for the rate card applied to this account')
    ] = None
    payment_terms: Annotated[
        payment_terms_1.PaymentTerms | None,
        Field(
            description='Payment terms agreed for this account. Binding for all invoices when the account is active.'
        ),
    ] = None
    credit_limit: Annotated[
        CreditLimit | None, Field(description='Maximum outstanding balance allowed')
    ] = None
    setup: Annotated[
        Setup | None,
        Field(
            description="Present when status is 'pending_approval'. Contains next steps for completing account activation."
        ),
    ] = None
    account_scope: account_scope_1.AccountScope | None = None
    governance_agents: Annotated[
        list[GovernanceAgent] | None,
        Field(
            description="Governance agent endpoint registered on this account. Exactly one entry per sync_governance's one-agent-per-account invariant. The array shape is preserved for wire compatibility with 3.0; `maxItems: 1` is load-bearing and mirrors the singular `governance_context` on the protocol envelope. Authentication credentials are write-only and not included in responses — use sync_governance to set or update credentials.",
            max_length=1,
            min_length=1,
        ),
    ] = None
    reporting_bucket: Annotated[
        ReportingBucket | None,
        Field(
            description="Cloud storage bucket where the seller delivers offline reporting files for this account. Seller provisions a dedicated bucket or a per-account prefix within a shared bucket, and grants the buyer read access out-of-band. Access MUST be scoped at the IAM layer so each account can only read its own prefix — bucket-wide grants are non-compliant even with per-account prefixes. Seller MUST revoke access when the account's status transitions to inactive, suspended, or closed. See security considerations for offline delivery in docs/media-buy/media-buys/optimization-reporting. Only present when the seller supports offline delivery (reporting_delivery_methods includes 'offline' in capabilities)."
        ),
    ] = None
    sandbox: Annotated[
        StrictBool | None,
        Field(
            description='When true, this is a sandbox account — no real platform calls, no real spend. For account-id namespaces, sandbox accounts are pre-existing test accounts on the platform discovered via list_accounts or supplied out-of-band. For buyer-declared accounts, sandbox is part of the natural key: the same brand/operator pair can have both a production and sandbox account.'
        ),
    ] = None
    notification_configs: Annotated[
        list[notification_config.NotificationConfig] | None,
        Field(
            description='Account-level webhook subscriptions for creative lifecycle/assignment changes, indicators.changed, account status, durable account-change wake-ups, wholesale feed changes, and reporting.delivery_ready. Buyers manage entries via sync_accounts and verify persisted state on list_accounts. account.change_recorded wakes receivers to drain list_account_changes; reporting.delivery_ready is repaired through get_reporting_status; indicator and assignment payloads are invalidations repaired completely through get_media_buys; list_creatives may provide a bounded reverse projection. Distinct from per-resource push_notification_config. Entries are keyed by account-scoped subscriber_id; credentials are write-only.',
            max_length=16,
        ),
    ] = None
    reporting_delivery_configs: Annotated[
        list[reporting_delivery_config_state.ReportingDeliveryConfigurationState] | None,
        Field(
            description="Resolved durable reporting delivery configurations owned by the authenticated caller for this account. list_accounts MUST expose only the calling principal's set. State and seller-issued destination_ref are returned; credentials and bearer profiles MUST NOT appear. Any setup URL is a secret-free authenticated entry point, not a bearer credential.",
            max_length=16,
        ),
    ] = None
    webhook_activity: Annotated[
        list[webhook_activity_record.WebhookActivityRecord] | None,
        Field(
            description='Recent webhook delivery attempts scoped to this account when the caller requested webhook activity on list_accounts and the seller surfaces the log. Includes account-anchored notifications such as account.status_changed and MAY include other account-level fires relevant to this account. Three-state presence follows the shared webhook_activity[] contract: omitted means unsupported or not requested, [] means supported but no retained fires, non-empty lists recent attempts most-recent-first.',
            max_length=200,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var account_id : str
var account_scope : AccountScope | None
var advertiser : str | None
var billing : BillingParty | None
var billing_entity : BusinessEntity | None
var billing_proxy : str | None
var brand : BrandReference | None
var credit_limit : CreditLimit | None
var currency : str | None
var destination_billing_entity : typing.Any | None
var ext : ExtensionObject | None
var governance_agents : list[GovernanceAgent] | None
var identity_change : AccountIdentityChange1 | AccountIdentityChange2 | None
var model_config
var name : str
var notification_configs : list[NotificationConfig] | None
var operator : str | None
var operator_unit : OperatorUnit | None
var payment_terms : PaymentTerms | None
var rate_card : str | None
var reporting_bucket : ReportingBucket | None
var reporting_delivery_configs : list[ReportingDeliveryConfigurationState] | None
var revision : int | None
var sandbox : bool | None
var setup : Setup | None
var status : AccountStatus
var timezone : str | None
var webhook_activity : list[WebhookActivityRecord] | None

Inherited members

class AccountAuthorization (**data: Any)
Expand source code
class AccountAuthorization(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    allowed_tasks: Annotated[
        list[AllowedTask],
        Field(
            description='Canonical snake_case task names the caller may invoke against this account (for example get_media_buys, buy_products, accept_proposal, control_media_buy, or sync_creatives). Absence of a task from this list means not permitted and returns SCOPE_INSUFFICIENT. Compact 3.2 tools are authorized by their own names; grants for deprecated get_products/create_media_buy/update_media_buy do not silently transfer across aliases.'
        ),
    ]
    field_scopes: Annotated[
        dict[str, list[str]] | None,
        Field(
            description='Optional per-task allowlist of request fields the caller may set. Keys are task names (which MUST also appear in allowed_tasks). Values are arrays of top-level request-field paths permitted for that task. When a task appears in field_scopes, requests to that task with any field outside the allowlist MUST be rejected with FIELD_NOT_PERMITTED. Compact product tools use their own task names and top-level fields such as criteria and refinements. Implicit framing fields are always permitted and do NOT need to appear in the allowlist — they identify the resource or shape the call rather than mutating business state. Tasks absent from field_scopes have no field-level restriction beyond what the task schema already enforces.'
        ),
    ] = None
    scope_name: Annotated[
        Literal['attestation_verifier'] | ScopeName | None,
        Field(
            description='Optional named scope identifier. When present, callers and the vendor agent can reason about the grant by name rather than by enumerating allowed_tasks and field_scopes. Modeled as a discriminated union so code generators produce a literal type for the standard scope(s) and a distinct type for agent-defined values — this prevents a typo of `attestation_verifier` from being silently accepted as a custom scope. Agent-defined scope names MUST use a `custom:` prefix to avoid collision with future standard scopes. The prefix is protocol-neutral: a signals agent, a governance agent, or a creative agent defines custom scopes the same way a media-buy sales agent does.'
        ),
    ] = None
    read_only: Annotated[
        StrictBool | None,
        Field(
            description='Convenience flag. When true, the caller is permitted only non-mutating tasks. Sellers MUST reject any mutation from a read-only caller with READ_ONLY_SCOPE. For the AdCP 3.2 product split, read-only permits list_products but rejects request_proposals, refine_proposals, and decline_proposals; a legacy get_products call is permitted only when the seller can guarantee the selected arm is a synchronous side-effect-free read. Sellers MAY omit this field; omission is equivalent to `false`. Callers MUST NOT infer read-only from `allowed_tasks` alone — the seller MUST set this explicitly when it applies.'
        ),
    ] = 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 allowed_tasks : list[AllowedTask]
var field_scopes : dict[str, list[str]] | None
var model_config
var read_only : bool | None
var scope_name : Literal['attestation_verifier'] | ScopeName | None

Inherited members

class AccountChange (**data: Any)
Expand source code
class AccountChange(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    change_id: Annotated[
        str,
        Field(
            description='Stable seller-generated identifier for this logical change. Retries and notification re-emissions reuse this identifier.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    recorded_at: Annotated[
        AwareDatetime,
        Field(
            description='Time the seller committed or durably observed the change. Feed order is defined by the cursor, not by this timestamp.'
        ),
    ]
    occurred_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Upstream business time when the change occurred, only when the seller can establish it reliably.'
        ),
    ] = None
    batch_id: Annotated[
        str | None,
        Field(
            description='Optional stable identifier grouping records produced by one committed operation or one external-source ingestion batch. Each independently repairable authoritative identity still receives its own record; batch_id does not change cursor ordering or notification identity.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    resource: Annotated[
        Resource,
        Field(
            description='Stable identity of the changed resource. Resource types are open for forward compatibility. account_id is always present; resource_id identifies the changed entity and parent_ids supplies any IDs needed to disambiguate nested resources.'
        ),
    ]
    action: Annotated[
        str,
        Field(
            description='Material change action. Standard values are created, discovered, updated, status_changed, linked, unlinked, deleted, and purged. Future standard or vendor-namespaced values are allowed; receivers MUST treat unknown values as generic invalidations.',
            max_length=100,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]{0,99}$',
        ),
    ]
    origin: Annotated[
        Origin,
        Field(
            description='Server-derived origin classification. The seller MUST NOT trust caller-supplied origin or actor claims.'
        ),
    ]
    resource_revision: Annotated[
        SchemaInt | str | None,
        Field(
            description='Post-change revision exposed by the repair read, when that resource family defines one.'
        ),
    ] = None
    changed_paths: Annotated[
        list[ChangedPath] | None,
        Field(
            description='Bounded set of RFC 6901 JSON Pointers naming material fields that changed. Values are intentionally omitted.',
            max_length=64,
        ),
    ] = None
    repair: Annotated[
        Repair,
        Field(
            description='Authoritative AdCP read the receiver uses to reconcile current state. The buyer constructs safe request arguments from the structured resource identity. A deleted or legally purged resource may instead declare unavailable with a categorical reason.'
        ),
    ]
    actor: Annotated[
        Actor | None,
        Field(
            description='Optional privacy-safe actor classification. Sellers MUST omit direct personal identifiers unless the authenticated caller is authorized for them.'
        ),
    ] = None
    reason: Annotated[
        str | None,
        Field(
            description='Short machine-readable reason code, when available.',
            max_length=100,
            pattern='^[a-z][a-z0-9_.-]{0,99}$',
        ),
    ] = None
    summary: Annotated[
        str | None,
        Field(
            description='Optional brief, untrusted human-readable summary. MUST NOT contain secrets or sensitive payload data.',
            max_length=500,
        ),
    ] = None
    ext: Annotated[
        ext_1.ExtensionObject | None,
        Field(
            description='Bounded vendor extensions. The entire encoded change record, including extensions, MUST NOT exceed 64 KiB and remains subject to the same secret/PII prohibitions.'
        ),
    ] = 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 action : str
var actor : Actor | None
var batch_id : str | None
var change_id : str
var changed_paths : list[ChangedPath] | None
var ext : ExtensionObject | None
var model_config
var occurred_at : pydantic.types.AwareDatetime | None
var origin : Origin
var reason : str | None
var recorded_at : pydantic.types.AwareDatetime
var repair : Repair
var resource : Resource
var resource_revision : int | str | None
var summary : str | None

Inherited members

class AccountChangeRecordedWebhook (**data: Any)
Expand source code
class AccountChangeRecordedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Sender-generated delivery key stable across retries of one fire. Deliberate re-emission uses a new key.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Logical notification identifier. Always equals change_id; retries and deliberate re-emissions of the same change retain it.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Literal['account.change_recorded'] = 'account.change_recorded'
    fired_at: AwareDatetime
    subscriber_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    account_id: Annotated[str, Field(max_length=255, min_length=1)]
    change_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    recorded_at: AwareDatetime
    resource: Annotated[
        Resource,
        Field(description='Resource identity copied from the corresponding account change record.'),
    ]
    action: Annotated[str, Field(max_length=100, min_length=1)]
    through_cursor: Annotated[
        str | None,
        Field(
            description='Optional advisory checkpoint at or after this change. It is a drain target, not a cursor the receiver may install without reading every intervening page.',
            max_length=4096,
            min_length=1,
        ),
    ] = None
    ext: Annotated[
        ext_1.ExtensionObject | None,
        Field(
            description='Bounded vendor extensions subject to the same secret/PII prohibitions as the base payload.'
        ),
    ] = 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 account_id : str
var action : str
var change_id : str
var ext : ExtensionObject | None
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var model_config
var notification_id : str
var notification_type : Literal['account.change_recorded']
var recorded_at : pydantic.types.AwareDatetime
var resource : Resource
var subscriber_id : str
var through_cursor : str | None

Inherited members

class AccountIdentityChange1 (**data: Any)
Expand source code
class AccountIdentityChange1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    status: Annotated[
        Literal['pending_approval'],
        Field(description='The seller is reviewing the requested transition.'),
    ] = 'pending_approval'
    requested_operator_identity: Annotated[
        operator_identity.OperatorIdentity,
        Field(description='Complete desired operator identity submitted by the buyer.'),
    ]
    requested_at: Annotated[
        AwareDatetime | None, Field(description='When the seller recorded the request.')
    ] = 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 model_config
var requested_at : pydantic.types.AwareDatetime | None
var requested_operator_identity : OperatorIdentity
var status : Literal['pending_approval']

Inherited members

class AccountIdentityChange2 (**data: Any)
Expand source code
class AccountIdentityChange2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    status: Annotated[
        Literal['rejected'],
        Field(
            description='The seller rejected the transition and retained the current canonical identity.'
        ),
    ] = 'rejected'
    requested_operator_identity: Annotated[
        operator_identity.OperatorIdentity,
        Field(description='Complete desired operator identity submitted by the buyer.'),
    ]
    requested_at: Annotated[
        AwareDatetime | None, Field(description='When the seller recorded the request.')
    ] = None
    reason: Annotated[
        str, Field(description='Human-readable rejection reason.', max_length=1000, 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 model_config
var reason : str
var requested_at : pydantic.types.AwareDatetime | None
var requested_operator_identity : OperatorIdentity
var status : Literal['rejected']

Inherited members

class AccountIdentityChangePreview1 (**data: Any)
Expand source code
class AccountIdentityChangePreview1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    outcome: Literal['would_apply'] = 'would_apply'
    requested_operator_identity: operator_identity.OperatorIdentity
    impacts: NonblockingImpacts

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 impacts : NonblockingImpacts
var model_config
var outcome : Literal['would_apply']
var requested_operator_identity : OperatorIdentity

Inherited members

class AccountIdentityChangePreview2 (**data: Any)
Expand source code
class AccountIdentityChangePreview2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    outcome: Literal['would_require_approval'] = 'would_require_approval'
    requested_operator_identity: operator_identity.OperatorIdentity
    impacts: NonblockingImpacts

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 impacts : NonblockingImpacts
var model_config
var outcome : Literal['would_require_approval']
var requested_operator_identity : OperatorIdentity

Inherited members

class AccountIdentityChangePreview3 (**data: Any)
Expand source code
class AccountIdentityChangePreview3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    outcome: Literal['blocked'] = 'blocked'
    requested_operator_identity: operator_identity.OperatorIdentity
    impacts: BlockedImpacts
    blockers: Annotated[list[Blocker], Field(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 blockers : list[Blocker]
var impacts : BlockedImpacts
var model_config
var outcome : Literal['blocked']
var requested_operator_identity : OperatorIdentity

Inherited members

class AccountReference1 (**data: Any)
Expand source code
class AccountReference1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    account_id: Annotated[
        str,
        Field(
            description="Seller-assigned account identifier. For upstream-managed account namespaces, this value comes from list_accounts; for seller-defined namespaces without a list_accounts surface, it is supplied out-of-band. Buyer-declared account sellers MAY echo account_id from sync_accounts as an internal handle, but they MUST continue accepting the account's current natural-key AccountRef on subsequent calls. A former key tombstoned by identity reconciliation returns ACCOUNT_MOVED to authorized callers."
        ),
    ]

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 account_id : str
var model_config

Inherited members

class AccountReference2 (**data: Any)
Expand source code
class AccountReference2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    brand: Annotated[
        brand_ref.BrandReference, Field(description='Brand reference identifying the advertiser')
    ]
    operator: Annotated[
        str,
        Field(
            description="Domain of the entity operating on the brand's behalf. When the brand operates directly, this is the brand's domain.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    operator_unit: Annotated[
        operator_unit_1.OperatorUnit | None,
        Field(
            description='Optional operator-owned business unit, agency seat, or platform account. Only id participates in the natural account key; name is mutable display metadata.'
        ),
    ] = None
    currency: Annotated[
        str | None,
        Field(
            description="Immutable ISO 4217 transaction currency when the seller's advertiser object is currency-bound. When present, this is part of the natural account key and media buys on the account MUST use it. Omit when currency is selected independently per media buy.",
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    timezone: Annotated[
        str | None,
        Field(
            description='Immutable account timezone. Include it in the natural key when get_adcp_capabilities.account.timezone declares account_fixed with buyer_selected; omit it for seller_fixed or seller_assigned accounts.',
            min_length=1,
        ),
    ] = None
    sandbox: Annotated[
        StrictBool | None,
        Field(
            description='When true, references the sandbox account for this brand/operator pair. Defaults to false (production account).'
        ),
    ] = 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 brand : BrandReference
var currency : str | None
var model_config
var operator : str
var operator_unit : OperatorUnit | None
var sandbox : bool | None
var timezone : str | None

Inherited members

class AccountSelection (*args, **kwds)
Expand source code
class AccountSelection(StrEnum):
    seller_assigned = 'seller_assigned'
    buyer_selected = 'buyer_selected'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var buyer_selected
var seller_assigned
class AccountStatusChangedWebhook (**data: Any)
Expand source code
class AccountStatusChangedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Sender-generated key stable across retries of the same fire. Sellers MUST generate a cryptographically random value (UUID v4 recommended) per distinct fire and reuse it on every retry of the same fire. Receivers MUST dedupe by this key, scoped to the authenticated sender identity.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Stable identifier for this logical account status transition. Stability key is (account_id, previous_status, status, observed_at): retries and re-emissions of the same transition reuse the id under a new idempotency_key, while a later transition cycle receives a new id.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Annotated[
        Literal['account.status_changed'],
        Field(
            description="Fixed notification type discriminator. Matches the value registered on the subscriber's event_types."
        ),
    ] = 'account.status_changed'
    fired_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller initiated this fire. Distinct from observed_at, which is when the seller recorded the account transition.'
        ),
    ]
    subscriber_id: Annotated[
        str,
        Field(
            description="Identifies which sync_accounts.accounts[].notification_configs[] entry is receiving this fire. Echoed verbatim from the entry's subscriber_id.",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    account_id: Annotated[
        str,
        Field(
            description='Seller-assigned account identifier whose status changed. Sellers MUST assign account_id before activating an account.status_changed subscriber, including accounts still pending external approval, so later pending_approval -> rejected or pending_approval -> active transitions can be delivered and repaired through list_accounts.'
        ),
    ]
    previous_status: Annotated[
        account_status.AccountStatus,
        Field(description='Account status immediately before this transition.'),
    ]
    status: Annotated[
        account_status.AccountStatus,
        Field(
            description='Account status after this transition. Receivers SHOULD treat this as advisory and re-read list_accounts for the authoritative account snapshot.'
        ),
    ]
    observed_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller recorded the account status transition. Used in the notification_id stability key; this is seller wall time for the transition, not webhook fire time.'
        ),
    ]
    reason_code: Annotated[
        ReasonCode,
        Field(
            description='Machine-readable reason for the transition. This is advisory routing/debug metadata; receivers MUST re-read list_accounts rather than relying on the reason code as the source of truth.'
        ),
    ]
    reason_detail: Annotated[
        str | None,
        Field(
            description='Optional short human-readable detail. Treat as untrusted text. Sellers MUST NOT include secrets, setup tokens, internal stack traces, or regulated financial details.',
            max_length=500,
        ),
    ] = None
    setup: Annotated[
        Setup | None,
        Field(
            description='Reduced setup hint when the new status requires human action. This block intentionally omits setup.url; receivers fetch the current setup URL from list_accounts if the caller is authorized to see it.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 account_id : str
var ext : ExtensionObject | None
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var model_config
var notification_id : str
var notification_type : Literal['account.status_changed']
var observed_at : pydantic.types.AwareDatetime
var previous_status : AccountStatus
var reason_code : ReasonCode
var reason_detail : str | None
var setup : Setup | None
var status : AccountStatus
var subscriber_id : str

Inherited members

class AccountTimezoneCapability (**data: Any)
Expand source code
class AccountTimezoneCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Annotated[
        Mode,
        Field(
            description='seller_fixed means every account uses fixed_timezone. account_fixed means each account has an immutable timezone returned on Account and selected or assigned during account establishment.'
        ),
    ]
    fixed_timezone: Annotated[
        str | None,
        Field(
            description='Seller-wide timezone used by every account. Required only for seller_fixed. Use UTC or an IANA timezone identifier.',
            min_length=1,
        ),
    ] = None
    account_selection: Annotated[
        AccountSelection | None,
        Field(
            description='How an account_fixed timezone is established. seller_assigned covers an existing upstream account or seller onboarding choice; buyer_selected requires timezone in buyer-declared sync_accounts provisioning.'
        ),
    ] = None
    supported_timezones: Annotated[
        list[SupportedTimezone] | None,
        Field(
            description='Exact timezone values accepted during buyer-selected account provisioning. Required when account_selection is buyer_selected so buyers can validate the choice before sync_accounts.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var account_selection : AccountSelection | None
var fixed_timezone : str | None
var mode : Mode
var model_config
var supported_timezones : list[SupportedTimezone] | None

Inherited members

class AccountWithAuthorization (**data: Any)
Expand source code
class AccountWithAuthorization(Account):
    authorization: Annotated[
        account_authorization.AccountAuthorization | None,
        Field(
            description="Optional. The caller's scope grant against this account. Vendor agents of any type (media-buy, signals, governance, creative, brand) that support scope introspection SHOULD populate this so callers can preempt SCOPE_INSUFFICIENT / FIELD_NOT_PERMITTED errors rather than discovering scope by trial and error. Media-buy sales agents claiming the `attestation_verifier` standard scope MUST populate it. Absence means the vendor agent does not advertise introspectable scope for this account — callers MUST NOT infer access from absence, and fall back to error-driven discovery via the RBAC error codes."
        ),
    ] = 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 authorization : AccountAuthorization | None
var model_config

Inherited members

class AccountingPeriod (**data: Any)
Expand source code
class AccountingPeriod(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    start: AwareDatetime
    end: AwareDatetime

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 end : pydantic.types.AwareDatetime
var model_config
var start : pydantic.types.AwareDatetime

Inherited members

class Action3 (*args, **kwds)
Expand source code
class Action3(StrEnum):
    cancel = 'cancel'
    extend_flight = 'extend_flight'
    shorten_flight = 'shorten_flight'
    update_flight_dates = 'update_flight_dates'
    increase_budget = 'increase_budget'
    decrease_budget = 'decrease_budget'
    reallocate_budget = 'reallocate_budget'
    update_budget_allocation = 'update_budget_allocation'
    update_targeting = 'update_targeting'
    update_pacing = 'update_pacing'
    update_bidding = 'update_bidding'
    update_frequency_caps = 'update_frequency_caps'
    update_media_buy_frequency_cap = 'update_media_buy_frequency_cap'
    add_packages = 'add_packages'
    remove_packages = 'remove_packages'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var add_packages
var cancel
var decrease_budget
var extend_flight
var increase_budget
var reallocate_budget
var remove_packages
var shorten_flight
var update_bidding
var update_budget_allocation
var update_flight_dates
var update_frequency_caps
var update_media_buy_frequency_cap
var update_pacing
var update_targeting
class Action4 (*args, **kwds)
Expand source code
class Action4(StrEnum):
    replace_creative = 'replace_creative'
    update_creative_assignments = 'update_creative_assignments'
    remove_creative = 'remove_creative'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var remove_creative
var replace_creative
var update_creative_assignments
class ActivationKey1 (**data: Any)
Expand source code
class ActivationKey1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[Literal['segment_id'], Field(description='Segment ID based targeting')] = 'segment_id'
    segment_id: Annotated[
        str,
        Field(description='The platform-specific segment identifier to use in campaign targeting'),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var segment_id : str
var type : Literal['segment_id']

Inherited members

class ActivationKey2 (**data: Any)
Expand source code
class ActivationKey2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[Literal['key_value'], Field(description='Key-value pair based targeting')] = 'key_value'
    key: Annotated[str, Field(description='The targeting parameter key')]
    value: Annotated[str, Field(description='The targeting parameter value')]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var key : str
var model_config
var type : Literal['key_value']
var value : str

Inherited members

class ActivationStatus (*args, **kwds)
Expand source code
class ActivationStatus(StrEnum):
    ready = 'ready'
    requires_activation = 'requires_activation'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var ready
var requires_activation
class Actor (**data: Any)
Expand source code
class Actor(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Type
    id: Annotated[
        str | None, Field(description='Opaque, redaction-safe actor reference.', max_length=255)
    ] = 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 id : str | None
var model_config
var type : Type

Inherited members

class AdInventoryConfiguration (**data: Any)
Expand source code
class AdInventoryConfiguration(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    expected_breaks: Annotated[
        SchemaInt, Field(description='Number of planned ad breaks in the installment', ge=0)
    ]
    total_ad_seconds: Annotated[
        SchemaInt | None, Field(description='Total seconds of ad time across all breaks', ge=0)
    ] = None
    max_ad_duration_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum duration in seconds for a single ad within a break. Buyers need this to know whether their creative fits.',
            ge=1,
        ),
    ] = None
    unplanned_breaks: Annotated[
        StrictBool | None,
        Field(
            description='Whether ad breaks are dynamic and driven by live conditions (sports timeouts, election coverage). When false, all breaks are pre-defined.'
        ),
    ] = None
    supported_formats: Annotated[
        list[str] | None,
        Field(
            description="Ad format types supported in breaks (e.g., 'video', 'audio', 'display')"
        ),
    ] = 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 expected_breaks : int
var max_ad_duration_seconds : int | None
var model_config
var supported_formats : list[str] | None
var total_ad_seconds : int | None
var unplanned_breaks : bool | None

Inherited members

class AdcpAssetGroupVocabularyRegistry (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class AdcpAssetGroupVocabularyRegistry(RootModel[Any]):
    root: Annotated[
        Any,
        Field(
            description='Canonical registry of asset_group_id values used in offering asset groups (OfferingAssetGroup) and in v2 product format declarations. Non-canonical IDs remain valid for platform-specific extensions; this registry codifies the recommended canonical set so that buyers and sellers share a vocabulary for the most common slot roles. Validators may emit soft warnings on non-canonical IDs to encourage convergence.\n\nThe registry covers everything the buyer ships in the manifest\'s `assets` map — both directly-rendered creative content (image, video, audio) AND content the seller consumes for production (script, creative_brief, video_brief). The seller dispatches per the format\'s slot declaration. There is no separate "inputs" map on the manifest; everything is an asset.\n\n**Two-tier boundary (normative).** This registry is the *canonical, portable* tier — IAB-aligned, platform-agnostic slot roles every adopter shares (`headline`, `body_text`, `main_image`, `cta`, `landing_page_url`, etc.). Platform-specific asset identifiers (e.g., YouTube video IDs, Pinterest pin IDs, TikTok video IDs, Snap attachment IDs, Meta Advantage+ creative IDs) MUST NOT be added here — they live on the canonical\'s `platform_extensions[]` (URI+digest reference to the platform\'s extension schema) so the canonical registry stays portable. Earlier drafts carried `youtube_video_id` and `pin_id` here; they were dropped in 3.1 GA precisely because adding them set precedent for every platform\'s identifier vocabulary to leak into the canonical tier, defeating the registry\'s portability purpose. Adopters needing to reference an existing platform-hosted asset attach a `platform_extensions[]` entry on the format declaration whose extension schema defines the platform-specific ID slot.',
            title='AdCP Asset Group Vocabulary Registry',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Any]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Any
class AdcpFormatShapeVocabularyRegistry (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class AdcpFormatShapeVocabularyRegistry(RootModel[Any]):
    root: Annotated[
        Any,
        Field(
            description='Canonical registry of `format_shape` values used on `ProductFormatDeclaration` when `format_kind: "custom"`. Captures recognized creative-structure patterns that are NOT yet first-class canonical formats — composed/coordinated/sponsorship shapes that high-end publishers and broadcast networks sell as headline products. Each registry entry names a global shape; the seller\'s actual structure lives in `format_schema` (URI+digest reference to the seller-hosted or AAO-mirrored schema) so buyer agents can fetch and validate against a real schema rather than reasoning over an opaque ext blob.\n\n**Two-layer extensibility:**\n- **Canonical** (`format_kind: image`, `video_vast`, etc.): full spec coverage, stable contract.\n- **Custom + format_shape + format_schema** (`format_kind: "custom"`): recognized pattern, classified against this vocabulary, but the params/slots structure is supplied by a fetchable schema rather than baked into AdCP.\n\nNon-canonical `format_shape` values remain valid (validators MAY soft-warn) so adopters CAN ship a shape that isn\'t yet in the registry — adding entries is a vocabulary PR, not a major-version bump. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group promotes it to a first-class canonical (creates `/schemas/formats/canonical/<name>.json`, adds the value to `canonical-format-kind.json`, retires the registry entry). See [adcp#3666](https://github.com/adcontextprotocol/adcp/issues/3666) for the promotion queue.\n\n**Promotion migration contract (normative).** Promotion is a wire-shape change for any consumer code branching on `format_kind == "custom"` — the same publisher\'s product now ships under `format_kind: "<promoted_name>"`. To avoid silent breakage:\n\n1. **Transition window.** When the working group promotes a `format_shape` to a first-class `format_kind`, sellers MAY ship a product under BOTH shapes during the transition window — two declarations on the same product\'s `format_options` array, one `format_kind: "custom"` + `format_shape: "<name>"` and one `format_kind: "<promoted_name>"`. Transition window is at minimum 90 days; the promotion PR sets the calendar.\n2. **Consumer-SDK deprecation warning.** SDKs encountering a `format_kind: "custom"` declaration whose `format_shape` matches an entry promoted to a first-class canonical SHOULD emit a structured deprecation warning via their lint channel (same pattern as `FORMAT_PROJECTION_FAILED` cross-boundary visibility) carrying `{ format_shape, promoted_to: format_kind, promotion_release, transition_end }`. Adopters branching on `format_kind == "custom"` past `transition_end` silently lose that publisher\'s inventory; the deprecation warning is the early signal.\n3. **`promotion_status` lifecycle.** When promotion is scheduled, the entry\'s `promotion_status` SHOULD update from `tracking — see adcp#3666` to `promoted to <format_kind> in <version>; transition ends <date>`. SDKs MAY read the registry at codegen / runtime to populate the deprecation warning\'s `transition_end`.\n4. **Producer-side hygiene.** After the transition window closes, sellers SHOULD drop the legacy `format_kind: "custom"` declaration and ship only the first-class canonical. Buyers MAY then assume `format_kind == "custom"` + `format_shape: "<name>"` is a long-tail / non-promoted shape, not a promoted-canonical-shipped-under-the-old-name.\n\nWithout this contract, every promotion event silently breaks adopter code branching on `format_kind == "custom"`. With it, the breakage surfaces as a structured warning during the transition window and adopters can update their branching ahead of the cutover.',
            title='AdCP Format Shape Vocabulary Registry',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Any]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Any
class AdcpVersionEnvelope (**data: Any)
Expand source code
class AdcpVersionEnvelope(AdCPBaseModel):
    adcp_version: Annotated[
        str | None,
        Field(
            description='Release-precision AdCP version (VERSION.RELEASE, e.g. "3.0", "3.1", "3.1-beta"). On a request: the buyer\'s release pin — the seller validates against its supported_versions and returns VERSION_UNSUPPORTED on cross-major mismatch, or downshifts to the highest supported release within the same major. On a response: the release the seller actually served — clients SHOULD validate the response against that release\'s schema, not against their pin. Patches are not negotiated; surface them as build_version on capabilities for operational visibility. When omitted, falls back to adcp_major_version (deprecated) or server default. Buyers SHOULD emit both adcp_version and adcp_major_version through 3.x to remain compatible with sellers that only read the legacy field. NORMALIZATION: SDKs that read full-semver values from bundle metadata (e.g. ComplianceIndex.published_version = "3.1.0-beta.1") MUST normalize to release-precision ("3.1-beta.1") before emitting on the wire — meta-field values are NOT valid wire values.',
            examples=['3.0', '3.1', '3.1-beta', '3.1-rc.1'],
            pattern='^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[a-zA-Z0-9](?:[a-zA-Z0-9.-]*[a-zA-Z0-9])?)?$',
        ),
    ] = None
    adcp_major_version: Annotated[
        SchemaInt | None,
        Field(
            deprecated=True,
            description="DEPRECATED in favor of adcp_version (release-precision string). Servers MUST continue to honor this field through 3.x. Removed in 4.0. Original semantics: the AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.",
            ge=1,
            le=99,
        ),
    ] = 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 adcp_major_version : int | None
var adcp_version : str | None
var model_config

Inherited members

class AdditionalItem (**data: Any)
Expand source code
class AdditionalItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: Annotated[str, Field(max_length=128, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,128}$')]
    purpose: Literal['additional'] = 'additional'
    input_rows: list[dict[str, Any]]
    canonical_utf8_base64: Annotated[
        str, Field(description='Base64 of the exact expected canonical UTF-8 bytes.', min_length=1)
    ]
    sha256: Annotated[str, Field(pattern='^[A-Fa-f0-9]{64}$')]

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 canonical_utf8_base64 : str
var input_rows : list[dict[str, typing.Any]]
var model_config
var name : str
var purpose : Literal['additional']
var sha256 : str

Inherited members

class AdjustmentMagnitudeItem (**data: Any)
Expand source code
class AdjustmentMagnitudeItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    control_total_name: Annotated[str, Field(max_length=128, min_length=1)]
    unit: Annotated[str, Field(max_length=32, min_length=1)]
    sample_count: Annotated[SchemaInt, Field(ge=1)]
    p50_absolute_delta: Annotated[str, Field(pattern='^(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$')]
    p95_absolute_delta: Annotated[str, Field(pattern='^(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$')]

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 control_total_name : str
var model_config
var p50_absolute_delta : str
var p95_absolute_delta : str
var sample_count : int
var unit : str

Inherited members

class AffectedEntityType (*args, **kwds)
Expand source code
class AffectedEntityType(StrEnum):
    product = 'product'
    signal = 'signal'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var product
var signal
class AgeRestriction (**data: Any)
Expand source code
class AgeRestriction(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    min: Annotated[SchemaInt, Field(description='Minimum age required', ge=13, le=99)]
    verification_required: Annotated[
        StrictBool | None,
        Field(description='Whether verified age (not inferred) is required for compliance'),
    ] = False
    accepted_methods: Annotated[
        list[age_verification_method.AgeVerificationMethod] | None,
        Field(
            description='Accepted verification methods. If omitted, any method the platform supports is acceptable.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var accepted_methods : list[AgeVerificationMethod] | None
var min : int
var model_config
var verification_required : bool | None

Inherited members

class AgentDeclarations (**data: Any)
Expand source code
class AgentDeclarations(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    async_adcp_versions: Annotated[
        list[AsyncAdcpVersion] | None,
        Field(
            description='AdCP minor versions, such as 3.2, whose asynchronous payload shapes (webhooks and other seller-initiated pushes) the caller can parse. The seller selects payload shapes from the accepted intersection; without a declaration the seller uses its advertised default.',
            max_length=8,
            min_length=1,
        ),
    ] = None
    webhook_signing_algorithms: Annotated[
        list[WebhookSigningAlgorithm] | None,
        Field(
            description="RFC 9421 webhook-signing algorithms the caller can verify. The accepted intersection with the seller's webhook_signing.algorithms MUST be non-empty when the caller has any active webhook subscriber; an empty intersection fails the sync request with UNSUPPORTED_FEATURE because delivery would be unverifiable.",
            min_length=1,
        ),
    ] = None
    experimental_features: Annotated[
        list[experimental_feature_id.ExperimentalFeatureId] | None,
        Field(
            description="Experimental feature identifiers, matching the seller's experimental_features vocabulary, that the caller opts into receiving in asynchronous payloads. Unknown identifiers are accepted and excluded from the intersection rather than rejected, so a caller can declare once across sellers with different surfaces.",
            max_length=32,
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var async_adcp_versions : list[AsyncAdcpVersion] | None
var experimental_features : list[ExperimentalFeatureId] | None
var model_config
var webhook_signing_algorithms : list[WebhookSigningAlgorithm] | None

Inherited members

class AgentEncryptionKey (**data: Any)
Expand source code
class AgentEncryptionKey(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kid: Annotated[
        str,
        Field(
            description='Key identifier. Opaque — MUST NOT encode geographic or deployment information.',
            max_length=8,
        ),
    ]
    kty: Annotated[Literal['OKP'], Field(description='JWK key type. Must be OKP for X25519.')] = 'OKP'
    crv: Annotated[
        Literal['X25519'], Field(description='Curve name. Must be X25519 for TMPX encryption.')
    ] = 'X25519'
    use: Annotated[
        Literal['enc'], Field(description='JWK use value. Must be enc for encryption keys.')
    ] = 'enc'
    x: Annotated[str, Field(description='Base64url-encoded X25519 public key (32 bytes).')]

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 crv : Literal['X25519']
var kid : str
var kty : Literal['OKP']
var model_config
var use : Literal['enc']
var x : str

Inherited members

class AgentNotificationConfig (**data: Any)
Expand source code
class AgentNotificationConfig(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    subscriber_id: Annotated[
        str,
        Field(
            description="Buyer- or registry-supplied identifier for this agent-level subscription endpoint. This is the stable logical key within the authenticated caller's agent-level notification config set: re-sending the same subscriber_id replaces that caller's subscriber URL, event_types, authentication selector, and active flag rather than creating a duplicate. Echoed on every webhook payload so multi-subscriber consumers can route by endpoint. MUST be unique within the submitted `notification_configs[]` array.",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    url: Annotated[
        AnyUrl,
        Field(
            description='Webhook endpoint URL. Same wire contract as `push-notification-config.url` and account-level `notification-config.url`: `format: "uri"`, no destination-port allowlist enforced by the protocol, SSRF protection via the IP-range check defined in docs/building/by-layer/L1/security.mdx#webhook-url-validation-ssrf. Sellers MUST validate URL syntax, HTTPS usage, hostname normalization, and reserved-range rejection when writing any config, including `active: false` configs. Sellers MUST complete an activation challenge or equivalent proof-of-control before treating a new or changed active subscriber as active.'
        ),
    ]
    event_types: Annotated[
        list[notification_type.NotificationType],
        Field(
            description="Notification types this subscriber wishes to receive on the registered `url`. Caller-anchored types (`capabilities.changed`, `principal.changed`) always fire principal-wide. Account-anchored types additionally require the explicit all_authorized_accounts acknowledgment. Account-anchored types (such as `creative.status_changed` or `account.change_recorded`) are also accepted here: each fire then covers only accounts the authenticated caller is authorized for at each delivery attempt — the subscription is standing, authorization is evaluated per attempt including retries, and losing account authority both stops new fires and suppresses queued retries carrying that account's data. Media-buy-anchored types are rejected on this surface; their per-buy cadence configuration stays on `push_notification_config`. Caller-level and account-level subscriptions to the same event are independent — both fire, and receivers dedupe by the event's logical `notification_id`.",
            min_length=1,
        ),
    ]
    all_authorized_accounts: Annotated[
        StrictBool | None,
        Field(
            description="Explicit scope acknowledgment required whenever event_types includes any account-anchored type: true states that this subscriber intentionally receives those events for every account the principal is authorized for at each delivery attempt. Subscribing an endpoint to all accounts is never implicit. Authorization is evaluated per delivery attempt, including retries: losing authority for an account suppresses queued retries carrying that account's data."
        ),
    ] = None
    include_future_event_types: Annotated[
        StrictBool | None,
        Field(
            description='When true, the seller also fires caller-eligible notification types added to the enum by later AdCP versions — but only types classified invalidation-only, whose payloads carry identifiers and a repair pointer rather than domain data. Payload-bearing types always require explicit enumeration in event_types; this flag never silently opts a caller into more-sensitive payloads. There is deliberately no wildcard event type. Receivers setting this MUST tolerate unknown notification_type values.'
        ),
    ] = False
    authentication: Annotated[
        Authentication | None,
        Field(
            deprecated=True,
            description="Legacy authentication selector. Same precedence and semantics as `push-notification-config.authentication` and account-level `notification-config.authentication`: presence opts the seller into Bearer or HMAC-SHA256 signing; absence selects the default RFC 9421 webhook profile keyed off the seller's brand.json `agents[]` JWKS. Deprecated; removed in AdCP 4.0. Credentials are write-only and MUST NOT be echoed on reads.",
        ),
    ] = None
    active: Annotated[
        StrictBool | None,
        Field(
            description='When false, the seller persists the configuration but suppresses fires. Use to pause a subscriber without losing the registration. Paused configs may skip only the outbound proof challenge while inactive; sellers MUST still enforce URL parsing, HTTPS, hostname normalization, and reserved-range rejection at write time. Reactivation requires full SSRF validation with connect pinning plus proof-of-control for any tuple without current valid proof.'
        ),
    ] = True
    ext: ext_1.ExtensionObject | 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 active : bool | None
var all_authorized_accounts : bool | None
var authentication : Authentication | None
var event_types : list[NotificationType]
var ext : ExtensionObject | None
var include_future_event_types : bool | None
var model_config
var subscriber_id : str
var url : pydantic.networks.AnyUrl

Inherited members

class AgentNotificationConfigState (**data: Any)
Expand source code
class AgentNotificationConfigState(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    subscriber_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    url: AnyUrl
    event_types: Annotated[list[notification_type.NotificationType], Field(min_length=1)]
    all_authorized_accounts: Annotated[
        StrictBool | None,
        Field(description='Echoed scope acknowledgment for account-anchored event types.'),
    ] = None
    include_future_event_types: Annotated[
        StrictBool | None, Field(description='Echoed from the desired configuration when set.')
    ] = None
    authentication: Annotated[Authentication | None, Field(deprecated=True)] = None
    active: StrictBool | None = True
    ext: ext_1.ExtensionObject | 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 active : bool | None
var all_authorized_accounts : bool | None
var authentication : Authentication | None
var event_types : list[NotificationType]
var ext : ExtensionObject | None
var include_future_event_types : bool | None
var model_config
var subscriber_id : str
var url : pydantic.networks.AnyUrl

Inherited members

class AgentProfilePayload (**data: Any)
Expand source code
class AgentProfilePayload(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    agent_url: AnyUrl | None = None
    name: str | None = None
    type: Type | None = None
    channels: StringArray | None = None
    property_types: StringArray | None = None
    markets: list[Market] | None = None
    categories: StringArray | None = None
    category_taxonomy: str | None = None
    format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Named-format profile projection. Use canonical `format_kinds` and `format_option_refs`.',
        ),
    ] = None
    format_kinds: list[str] | None = None
    tags: StringArray | None = None
    delivery_types: StringArray | None = None
    property_count: Annotated[SchemaInt | None, Field(ge=0)] = None
    publisher_count: Annotated[SchemaInt | None, Field(ge=0)] = None
    has_tmp: StrictBool | None = None
    updated_at: AwareDatetime | 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

Subclasses

Class variables

var agent_url : pydantic.networks.AnyUrl | None
var categories : StringArray | None
var category_taxonomy : str | None
var channels : StringArray | None
var delivery_types : StringArray | None
var format_ids : list[FormatReferenceStructuredObject] | None
var format_kinds : list[str] | None
var has_tmp : bool | None
var markets : list[Market] | None
var model_config
var name : str | None
var property_count : int | None
var property_types : StringArray | None
var publisher_count : int | None
var tags : StringArray | None
var type : Type | None
var updated_at : pydantic.types.AwareDatetime | None

Inherited members

class AgentReportingDestination1 (**data: Any)
Expand source code
class AgentReportingDestination1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Annotated[
        Literal['file_transfer'],
        Field(
            description='Discriminator. Producer publishes immutable files plus a manifest to caller-controlled object storage.'
        ),
    ] = 'file_transfer'
    destination_id: Annotated[
        str,
        Field(
            description='Caller-selected stable logical key, unique within this seller relationship. Reusing it replaces desired configuration; when proof-bound coordinates or the accepted delivery contract change, the seller issues a new immutable destination_ref generation while retaining the old reference for existing account bindings and reporting history.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    operator_id: Annotated[
        str | None,
        Field(
            description="Optional agent-scoped label naming the operator this destination serves, for per-operator isolation, audit, and offboarding under an agent principal. It is the principal's own bookkeeping and confers no identity or authority: sellers MUST NOT link, dedupe, or authorize across principals based on matching operator labels or domains.",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ] = None
    active: Annotated[
        StrictBool,
        Field(
            description='True permits use. False suspends the destination: the seller MUST stop initiating new deliveries to every generation of this destination_id within the advertised suspension interval, and new account-level delivery configurations MUST NOT select it. Suspension does not delete caller-owned data already delivered.'
        ),
    ]
    provider: delivery_provider.DeliveryProvider
    transport: Annotated[
        str,
        Field(
            description='Open provider transport name, such as s3, gcs, or azure_blob.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    location: Annotated[
        str,
        Field(
            description='Provider-native bucket/prefix locator, such as s3://bucket/prefix/ or abfss://container@account.dfs.core.windows.net/path. Printable ASCII without whitespace, \'?\', \'#\', \'%\', \'"\', \'<\', or \'>\'. Never a credential or signed URL; sellers additionally screen and normalize per the secret_rejection and normalization rules.',
            max_length=2048,
            min_length=1,
            pattern='^[!$&-;=@-~]+$',
        ),
    ]
    accepted_formats: Annotated[
        list[AcceptedFormat],
        Field(
            description='Physical formats accepted by this file-transfer destination.', min_length=1
        ),
    ]
    accepted_verification_profiles: (
        reporting_verification_profile_set.ReportingVerificationProfileSet
    )

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var accepted_formats : list[AcceptedFormat]
var accepted_verification_profiles : ReportingVerificationProfileSet
var active : bool
var destination_id : str
var location : str
var model_config
var operator_id : str | None
var pattern : Literal['file_transfer']
var provider : DeliveryProvider
var transport : str

Inherited members

class AgentReportingDestination2 (**data: Any)
Expand source code
class AgentReportingDestination2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Annotated[
        Literal['warehouse_materialization'],
        Field(
            description='Discriminator. Producer or its connector commits reporting revisions into a caller-owned warehouse relation.'
        ),
    ] = 'warehouse_materialization'
    destination_id: Annotated[
        str,
        Field(
            description='Caller-selected stable logical key, unique within this seller relationship. Reusing it replaces desired configuration; when proof-bound coordinates or the accepted delivery contract change, the seller issues a new immutable destination_ref generation while retaining the old reference for existing account bindings and reporting history.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    operator_id: Annotated[
        str | None,
        Field(
            description="Optional agent-scoped label naming the operator this destination serves, for per-operator isolation, audit, and offboarding under an agent principal. It is the principal's own bookkeeping and confers no identity or authority: sellers MUST NOT link, dedupe, or authorize across principals based on matching operator labels or domains.",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ] = None
    active: Annotated[
        StrictBool,
        Field(
            description='True permits use. False suspends the destination: the seller MUST stop initiating new deliveries to every generation of this destination_id within the advertised suspension interval, and new account-level delivery configurations MUST NOT select it. Suspension does not delete caller-owned data already delivered.'
        ),
    ]
    provider: delivery_provider.DeliveryProvider
    transport: Annotated[
        str,
        Field(
            description='Open provider transport name, such as bigquery, snowflake, or databricks_sql.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    location: Annotated[
        str,
        Field(
            description='Provider-native project/dataset, database/schema, or catalog/schema locator. Printable ASCII without whitespace, \'?\', \'#\', \'%\', \'"\', \'<\', or \'>\'. Never a credential or signed URL; sellers additionally screen and normalize per the secret_rejection and normalization rules.',
            max_length=2048,
            min_length=1,
            pattern='^[!$&-;=@-~]+$',
        ),
    ]
    accepted_verification_profiles: (
        reporting_verification_profile_set.ReportingVerificationProfileSet
    )

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var accepted_verification_profiles : ReportingVerificationProfileSet
var active : bool
var destination_id : str
var location : str
var model_config
var operator_id : str | None
var pattern : Literal['warehouse_materialization']
var provider : DeliveryProvider
var transport : str

Inherited members

class AgentReportingDestination3 (**data: Any)
Expand source code
class AgentReportingDestination3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Annotated[
        Literal['dataset_share'],
        Field(
            description='Discriminator. Producer retains and versions the dataset; the named recipient reads provider-hosted share objects.'
        ),
    ] = 'dataset_share'
    destination_id: Annotated[
        str,
        Field(
            description='Caller-selected stable logical key, unique within this seller relationship. Reusing it replaces desired configuration; when proof-bound coordinates or the accepted delivery contract change, the seller issues a new immutable destination_ref generation while retaining the old reference for existing account bindings and reporting history.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    operator_id: Annotated[
        str | None,
        Field(
            description="Optional agent-scoped label naming the operator this destination serves, for per-operator isolation, audit, and offboarding under an agent principal. It is the principal's own bookkeeping and confers no identity or authority: sellers MUST NOT link, dedupe, or authorize across principals based on matching operator labels or domains.",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ] = None
    active: Annotated[
        StrictBool,
        Field(
            description='True permits use. False suspends the destination: the seller MUST stop publishing new revisions to every generation of this destination_id within the advertised suspension interval, and new account-level delivery configurations MUST NOT select it. Suspension does not delete caller-owned data already delivered or revoke provider-side grants by itself.'
        ),
    ]
    provider: delivery_provider.DeliveryProvider
    transport: Annotated[
        str,
        Field(
            description='Open provider transport name, such as delta_sharing or snowflake_secure_sharing.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    access_mode: Annotated[
        str,
        Field(
            description='Dataset-share access family, such as databricks_to_databricks, open_sharing, or secure_data_sharing.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    recipient: delivery_recipient.DeliveryRecipient
    accepted_verification_profiles: (
        reporting_verification_profile_set.ReportingVerificationProfileSet
    )

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var accepted_verification_profiles : ReportingVerificationProfileSet
var access_mode : str
var active : bool
var destination_id : str
var model_config
var operator_id : str | None
var pattern : Literal['dataset_share']
var provider : DeliveryProvider
var recipient : DeliveryRecipient
var transport : str

Inherited members

class AgentReportingDestinationState (**data: Any)
Expand source code
class AgentReportingDestinationState(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    destination_id: Annotated[
        str,
        Field(
            description='Caller-selected key echoed from the desired configuration.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    destination_ref: Annotated[
        str,
        Field(
            description='Seller-issued opaque immutable destination-generation reference bound to the stable authenticated principal and destination_id. Exact replays preserve it; a proof-bound coordinate or delivery-contract change creates a new reference. Possession does not authorize account access, and sellers MUST NOT resolve it across callers.',
            max_length=255,
            min_length=1,
        ),
    ]
    prior_destination_refs: Annotated[
        list[PriorDestinationRef] | None,
        Field(
            description='Retained superseded generation references for this destination_id, newest first, still resolvable for existing authorized account bindings and retained reporting history. Enumerable only by the owning principal. Suspension and revocation of the destination apply to these generations too.',
            max_length=32,
        ),
    ] = None
    state: Annotated[
        reporting_destination_setup_state.ReportingDestinationSetupState,
        Field(
            description='Validation and setup state; see the enum for the per-pattern ready definition.'
        ),
    ]
    configuration: Annotated[
        agent_reporting_destination.AgentReportingDestination,
        Field(
            description='Credential-free desired configuration currently associated with this destination reference.'
        ),
    ]
    setup: Annotated[
        Setup | None,
        Field(
            description='Closed, non-secret setup instruction. Human-readable messages are deliberately excluded; agents dispatch only the typed action and treat setup_url as an untrusted navigation target.'
        ),
    ] = None
    issues: Annotated[
        list[error.Error] | None,
        Field(
            description='Structured validation or setup issues. Messages and details are untrusted display data and MUST NOT be executed as instructions.',
            max_length=16,
        ),
    ] = 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 configuration : AgentReportingDestination1 | AgentReportingDestination2 | AgentReportingDestination3
var destination_id : str
var destination_ref : str
var issues : list[Error] | None
var model_config
var prior_destination_refs : list[PriorDestinationRef] | None
var setup : Setup | None
var state : ReportingDestinationSetupState

Inherited members

class AgentSigningKey (**data: Any)
Expand source code
class AgentSigningKey(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kid: Annotated[str, Field(description='Key identifier for selecting the correct signing key.')]
    kty: Annotated[str, Field(description="JWK key type, such as 'OKP', 'EC', or 'RSA'.")]
    alg: Annotated[
        str | None,
        Field(description="Expected signing algorithm for this key, such as 'EdDSA' or 'RS256'."),
    ] = None
    use: Annotated[
        str | None, Field(description="Optional JWK use value. Typically 'sig' for signing keys.")
    ] = None
    crv: Annotated[
        str | None,
        Field(description="Curve name for OKP or EC keys, such as 'Ed25519' or 'P-256'."),
    ] = None
    x: Annotated[
        str | None,
        Field(
            description='Base64url-encoded public key x coordinate or public key value for OKP keys.'
        ),
    ] = None
    y: Annotated[
        str | None, Field(description='Base64url-encoded public key y coordinate for EC keys.')
    ] = None
    n: Annotated[str | None, Field(description='Base64url-encoded RSA modulus.')] = None
    e: Annotated[str | None, Field(description='Base64url-encoded RSA public exponent.')] = None
    revoked_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Optional revocation timestamp. When present, verifiers MUST reject any signature produced with this key whose signing epoch (or equivalent time reference) is at or after this timestamp. The key may continue to appear in the trust anchor during a grace period so caches that have not yet refreshed still find the key and can evaluate the revocation marker. Keys past their revocation can be removed once the cache TTL (recommended: 5 minutes) has elapsed across all verifiers.'
        ),
    ] = 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 alg : str | None
var crv : str | None
var e : str | None
var kid : str
var kty : str
var model_config
var n : str | None
var revoked_at : pydantic.types.AwareDatetime | None
var use : str | None
var x : str | None
var y : str | None

Inherited members

class AgentWebhookChallenge (**data: Any)
Expand source code
class AgentWebhookChallenge(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['webhook.challenge'],
        Field(description='Discriminator for endpoint proof-of-control challenges.'),
    ] = 'webhook.challenge'
    scope: Annotated[
        Literal['agent'],
        Field(description='Discriminator for agent-level endpoint proof challenges.'),
    ] = 'agent'
    challenge: Annotated[
        str,
        Field(
            description='Opaque, cryptographically random value that the receiver must echo in the response body. Recommended encoding: base64url without padding.',
            max_length=255,
            min_length=32,
            pattern='^[A-Za-z0-9_.:-]{32,255}$',
        ),
    ]
    subscriber_id: Annotated[
        str,
        Field(
            description='Buyer-supplied subscriber identifier from the caller-scoped notification_configs[] entry being challenged.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    seller_agent_url: Annotated[
        AnyUrl,
        Field(
            description='Exact seller agent URL whose RFC 9421 webhook profile key signs this challenge and that will send subsequent webhooks.'
        ),
    ]
    delivery_auth: Annotated[
        DeliveryAuth,
        Field(
            description='Authentication/signing mode the seller will use for subsequent webhooks delivered to this notification config.'
        ),
    ]
    event_types: Annotated[
        list[Literal['capabilities.changed']],
        Field(
            description='Normalized agent-level notification types requested by the subscriber at the time of the challenge. Part of the endpoint proof scope; changing event_types[] requires a fresh challenge before the new set can become active. Currently only `capabilities.changed` is valid.',
            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 challenge : str
var delivery_auth : DeliveryAuth
var event_types : list[typing.Literal['capabilities.changed']]
var model_config
var scope : Literal['agent']
var seller_agent_url : pydantic.networks.AnyUrl
var subscriber_id : str
var type : Literal['webhook.challenge']

Inherited members

class AgenticadvertisingOrgVerificationTokenClaims (**data: Any)
Expand source code
class AgenticadvertisingOrgVerificationTokenClaims(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    iss: Literal['https://aao.org'] = 'https://aao.org'
    sub: AnyUrl
    aud: Literal['aao-verification'] = 'aao-verification'
    jti: Annotated[str, Field(min_length=1)]
    iat: Annotated[SchemaInt, Field(ge=0)]
    exp: Annotated[SchemaInt, Field(ge=0)]
    agent_url: AnyUrl
    role: Role
    verified_specialisms: Annotated[list[str], Field(min_length=1)]
    verification_modes: Annotated[list[VerificationTokenMode], Field(min_length=1)]
    grading_profile: Annotated[
        VerificationTokenGradingProfile | None,
        Field(
            description='Grading policy that produced the badge. Absence on a historical token means Legacy; verification_modes remains an independent evidence axis.'
        ),
    ] = None
    first_failing_spec_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Start of the current Strict Spec failure episode. Omitted when no Strict Spec failure clock is active. The registry remains authoritative for real-time status.'
        ),
    ] = None
    adcp_version: Annotated[str | None, Field(pattern='^[1-9][0-9]*\\.[0-9]+$')] = None
    protocol_version: str | 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 adcp_version : str | None
var agent_url : pydantic.networks.AnyUrl
var aud : Literal['aao-verification']
var exp : int
var first_failing_spec_at : pydantic.types.AwareDatetime | None
var grading_profile : VerificationTokenGradingProfile | None
var iat : int
var iss : Literal['https://aao.org']
var jti : str
var model_config
var protocol_version : str | None
var role : Role
var sub : pydantic.networks.AnyUrl
var verification_modes : list[VerificationTokenMode]
var verified_specialisms : list[str]

Inherited members

class Aggregation (*args, **kwds)
Expand source code
class Aggregation(StrEnum):
    sum = 'sum'
    count = 'count'  # type: ignore[assignment]
    min = 'min'
    max = 'max'
    average = 'average'
    ratio = 'ratio'
    last = 'last'
    custom = 'custom'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var average
var count
var custom
var last
var max
var min
var ratio
var sum
class AllowedInterval (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AllowedInterval(ScalarInt):
    __slots__ = ()
    _constraints = {'ge': 1}

An int generated from a JSON Schema integer root.

Validates the way SchemaInt validates an integer field: strict, so "1" and True are refused, with a float carrying no fractional part narrowed to int because JSON Schema counts it as one.

Ancestors

  • adcp.types._scalar.ScalarInt
  • adcp.types._scalar._ScalarRoot
  • builtins.int
class AllowedTargetingMode (*args, **kwds)
Expand source code
class AllowedTargetingMode(StrEnum):
    include = 'include'
    exclude = 'exclude'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var exclude
var include
class AllowedTask (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AllowedTask(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-z][a-z0-9_]*$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class AllowedValue (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AllowedValue(ScalarInt):
    __slots__ = ()
    _constraints = {'ge': 1}

An int generated from a JSON Schema integer root.

Validates the way SchemaInt validates an integer field: strict, so "1" and True are refused, with a float carrying no fractional part narrowed to int because JSON Schema counts it as one.

Ancestors

  • adcp.types._scalar.ScalarInt
  • adcp.types._scalar._ScalarRoot
  • builtins.int
class AppItem (**data: Any)
Expand source code
class AppItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    app_id: Annotated[
        str,
        Field(
            description='Buyer-assigned unique identifier for this app item. Used for catalog deduplication and content_ids matching on install and launch events.'
        ),
    ]
    name: Annotated[
        str,
        Field(
            description="App display name as shown in the store (e.g., 'Puzzle Quest: Match 3', 'Acme Banking')."
        ),
    ]
    platform: Annotated[
        Platform,
        Field(
            description='Target platform. iOS and Android are separate items because they have distinct store identifiers and attribution mechanisms.'
        ),
    ]
    bundle_id: Annotated[
        str | None,
        Field(
            description="Reverse-domain bundle identifier (e.g., 'com.acmegames.puzzlequest'). The universal store identifier: required for Android (Google Play), also used for iOS MMP attribution, SKAN matching, and app-ads.txt verification. Distinct from app_id, which is a buyer-assigned catalog key."
        ),
    ] = None
    apple_id: Annotated[
        str | None,
        Field(
            description="Numeric Apple App Store ID (e.g., '389801252'). Required for Apple Search Ads and iOS platforms that use the numeric ID rather than bundle_id.",
            pattern='^[0-9]+$',
        ),
    ] = None
    description: Annotated[
        str | None,
        Field(
            description='App description. Platforms typically pull this from the store listing automatically; supply here to override or for platforms that require it in the request.'
        ),
    ] = None
    category: Annotated[
        str | None,
        Field(
            description="Primary store category (e.g., 'games', 'productivity', 'finance', 'health_fitness', 'social_networking')."
        ),
    ] = None
    genre: Annotated[
        str | None,
        Field(
            description="Sub-genre within the category. Particularly relevant for games (e.g., 'puzzle', 'strategy', 'rpg', 'casual', 'simulation', 'action')."
        ),
    ] = None
    icon_url: Annotated[
        AnyUrl | None, Field(description='App icon image URL. Typically 1024×1024 px.')
    ] = None
    screenshots: Annotated[
        list[AnyUrl] | None,
        Field(
            description='App store screenshot URLs. Used by platforms for creative generation when native store assets are not available.',
            min_length=1,
        ),
    ] = None
    preview_video_url: Annotated[
        AnyUrl | None,
        Field(description='App preview or gameplay video URL for use in video ad creatives.'),
    ] = None
    store_url: Annotated[
        AnyUrl | None,
        Field(
            description="Direct link to the app's store listing (Apple App Store or Google Play)."
        ),
    ] = None
    deep_link_url: Annotated[
        AnyUrl | None,
        Field(
            description="Deep link URI for re-engagement campaigns targeting existing users. Use Universal Links (iOS) or App Links (Android) where available (e.g., 'https://acmegames.com/app/level/5'). Falls back to URI scheme (e.g., 'acmegames://level/5') when universal links are not configured."
        ),
    ] = None
    price: Annotated[
        price_1.Price | None,
        Field(description='App download price. Set amount to 0 for free apps.'),
    ] = None
    rating: Annotated[
        StrictFloat | None,
        Field(
            description='Average store rating (0–5). Use 0 to indicate no ratings yet.',
            ge=0.0,
            le=5.0,
        ),
    ] = None
    rating_count: Annotated[
        SchemaInt | None, Field(description='Total number of store ratings.', ge=0)
    ] = None
    content_rating: Annotated[
        str | None,
        Field(
            description="Age or content rating (e.g., '4+', '12+', 'Everyone', 'Teen', 'PEGI 12'). Format depends on store and region."
        ),
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering and targeting (e.g., 'multiplayer', 'offline', 'no-ads', 'subscription').",
            min_length=1,
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this app. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (promotional hero), 'images_vertical' (9:16 for Snap, Stories), 'images_square' (1:1 for display), 'video' (gameplay or demo video). Supplements icon_url and screenshots for platform-specific format requirements.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 app_id : str
var apple_id : str | None
var assets : list[OfferingAssetGroup] | None
var bundle_id : str | None
var category : str | None
var content_rating : str | None
var description : str | None
var ext : ExtensionObject | None
var genre : str | None
var icon_url : pydantic.networks.AnyUrl | None
var model_config
var name : str
var platform : Platform
var preview_video_url : pydantic.networks.AnyUrl | None
var price : Price | None
var rating : float | None
var rating_count : int | None
var screenshots : list[pydantic.networks.AnyUrl] | None
var store_url : pydantic.networks.AnyUrl | None
var tags : list[str] | None

Inherited members

class ApplicablePackageId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ApplicablePackageId(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}
    _json_schema_extra = {
        'description': 'A package identifier to which a package-scoped media-buy action currently applies.',
        'title': 'Applicable Package ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class AppliesTo1 (**data: Any)
Expand source code
class AppliesTo1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['public'] = 'public'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var scope : Literal['public']

Inherited members

class AppliesTo2 (**data: Any)
Expand source code
class AppliesTo2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['account'] = 'account'
    account_ids: Annotated[
        list[str] | None,
        Field(
            description="Optional. When present, names the accounts whose overlays are affected. When omitted, subscribers infer that their own principal's overlay is affected (they received the event because the per-subscriber scope filter routed it to them).",
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var account_ids : list[str] | None
var model_config
var scope : Literal['adcp.types.domains.core.account']

Inherited members

class AppliesToOutputCapabilityId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AppliesToOutputCapabilityId(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-zA-Z0-9_-]+$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ApprovalStatus (*args, **kwds)
Expand source code
class ApprovalStatus(StrEnum):
    pending = 'pending'
    approved = 'approved'
    rejected = 'rejected'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var approved
var pending
var rejected
class Artifact (**data: Any)
Expand source code
class Artifact(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    property_id: Annotated[
        identifier.Identifier, Field(description='Property where the artifact appears')
    ]
    artifact_id: Annotated[str, Field(description='Artifact identifier within the property')]

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 artifact_id : str
var model_config
var property_id : Identifier

Inherited members

class AssetPoolBinding (**data: Any)
Expand source code
class AssetPoolBinding(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['asset_pool'] = 'asset_pool'
    asset_id: Annotated[
        str,
        Field(
            description="The asset_id from the format's assets array. Identifies which individual template slot this binding applies to."
        ),
    ]
    asset_group_id: Annotated[
        str,
        Field(
            description="The asset_group_id on the catalog item's assets array to pull from (e.g., 'images_landscape', 'images_vertical', 'logo')."
        ),
    ]
    ext: ext_1.ExtensionObject | 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 asset_group_id : str
var asset_id : str
var ext : ExtensionObject | None
var kind : Literal['asset_pool']
var model_config

Inherited members

class AssetSource (*args, **kwds)
Expand source code
class AssetSource(StrEnum):
    buyer_uploaded = 'buyer_uploaded'
    publisher_host_recorded = 'publisher_host_recorded'
    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_host_recorded
var publisher_owned_reference
var seller_human_designed
var seller_pre_rendered_from_brief
class Assets10 (**data: Any)
Expand source code
class Assets10(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['audio'] = 'audio'
    requirements: audio_asset_requirements.AudioAssetRequirements | 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 asset_type : Literal['audio']
var item_type : Literal['individual']
var model_config
var requirements : AudioAssetRequirements | None

Inherited members

class Assets11 (**data: Any)
Expand source code
class Assets11(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['text'] = 'text'
    requirements: text_asset_requirements.TextAssetRequirements | 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 asset_type : Literal['text']
var item_type : Literal['individual']
var model_config
var requirements : TextAssetRequirements | None

Inherited members

class Assets12 (**data: Any)
Expand source code
class Assets12(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['markdown'] = 'markdown'
    requirements: markdown_asset_requirements.MarkdownAssetRequirements | 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 asset_type : Literal['markdown']
var item_type : Literal['individual']
var model_config
var requirements : MarkdownAssetRequirements | None

Inherited members

class Assets13 (**data: Any)
Expand source code
class Assets13(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['html'] = 'html'
    requirements: html_asset_requirements.HtmlAssetRequirements | 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 asset_type : Literal['html']
var item_type : Literal['individual']
var model_config
var requirements : HtmlAssetRequirements | None

Inherited members

class Assets14 (**data: Any)
Expand source code
class Assets14(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['css'] = 'css'
    requirements: css_asset_requirements.CssAssetRequirements | 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 asset_type : Literal['css']
var item_type : Literal['individual']
var model_config
var requirements : CssAssetRequirements | None

Inherited members

class Assets15 (**data: Any)
Expand source code
class Assets15(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['javascript'] = 'javascript'
    requirements: javascript_asset_requirements.JavascriptAssetRequirements | 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 asset_type : Literal['javascript']
var item_type : Literal['individual']
var model_config
var requirements : JavascriptAssetRequirements | None

Inherited members

class Assets16 (**data: Any)
Expand source code
class Assets16(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['zip'] = 'zip'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['zip']
var item_type : Literal['individual']
var model_config

Inherited members

class Assets17 (**data: Any)
Expand source code
class Assets17(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['vast'] = 'vast'
    requirements: vast_asset_requirements.VastAssetRequirements | 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 asset_type : Literal['vast']
var item_type : Literal['individual']
var model_config
var requirements : VastAssetRequirements | None

Inherited members

class Assets18 (**data: Any)
Expand source code
class Assets18(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['daast'] = 'daast'
    requirements: daast_asset_requirements.DaastAssetRequirements | 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 asset_type : Literal['daast']
var item_type : Literal['individual']
var model_config
var requirements : DaastAssetRequirements | None

Inherited members

class Assets19 (**data: Any)
Expand source code
class Assets19(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['url'] = 'url'
    requirements: url_asset_requirements.UrlAssetRequirements | 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 asset_type : Literal['url']
var item_type : Literal['individual']
var model_config
var requirements : UrlAssetRequirements | None

Inherited members

class Assets20 (**data: Any)
Expand source code
class Assets20(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['webhook'] = 'webhook'
    requirements: webhook_asset_requirements.WebhookAssetRequirements | 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 asset_type : Literal['webhook']
var item_type : Literal['individual']
var model_config
var requirements : WebhookAssetRequirements | None

Inherited members

class Assets21 (**data: Any)
Expand source code
class Assets21(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['brief'] = 'brief'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['brief']
var item_type : Literal['individual']
var model_config

Inherited members

class Assets22 (**data: Any)
Expand source code
class Assets22(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['catalog'] = 'catalog'
    requirements: catalog_requirements.CatalogRequirements | 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 asset_type : Literal['adcp.types.domains.core.catalog']
var item_type : Literal['individual']
var model_config
var requirements : CatalogRequirements | None

Inherited members

class Assets23 (**data: Any)
Expand source code
class Assets23(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['display_tag'] = '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 asset_type : Literal['display_tag']
var item_type : Literal['individual']
var model_config

Inherited members

class Assets24 (**data: Any)
Expand source code
class Assets24(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['published_post'] = 'published_post'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['published_post']
var item_type : Literal['individual']
var model_config

Inherited members

class Assets25 (**data: Any)
Expand source code
class Assets25(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['card'] = 'card'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['card']
var item_type : Literal['individual']
var model_config

Inherited members

class Assets26 (**data: Any)
Expand source code
class Assets26(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['pixel_tracker'] = 'pixel_tracker'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['pixel_tracker']
var item_type : Literal['individual']
var model_config

Inherited members

class Assets27 (**data: Any)
Expand source code
class Assets27(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['vast_tracker'] = 'vast_tracker'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['vast_tracker']
var item_type : Literal['individual']
var model_config

Inherited members

class Assets28 (**data: Any)
Expand source code
class Assets28(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['daast_tracker'] = 'daast_tracker'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['daast_tracker']
var item_type : Literal['individual']
var model_config

Inherited members

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

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_group_id : str
var assets : list[Assets31 | Assets32 | Assets33 | Assets34 | Assets35 | Assets36 | Assets37 | Assets38 | Assets40 | Assets41 | Assets42 | Assets43 | UnknownGroupAsset]
var item_type : Literal['repeatable_group']
var max_count : int
var min_count : int
var model_config
var required : bool
var selection_mode : SelectionMode | None
class Assets94 (**data: Any)
Expand source code
class Assets29(AdCPBaseModel):
    item_type: Annotated[
        Literal['repeatable_group'],
        Field(description='Discriminator indicating this is a repeatable asset group'),
    ] = 'repeatable_group'
    asset_group_id: Annotated[
        str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')")
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether this asset group is required. If true, at least min_count repetitions must be provided.'
        ),
    ]
    min_count: Annotated[
        SchemaInt,
        Field(
            description='Minimum number of repetitions required (if group is required) or allowed (if optional)',
            ge=0,
        ),
    ]
    max_count: Annotated[
        SchemaInt, Field(description='Maximum number of repetitions allowed', ge=1)
    ]
    selection_mode: Annotated[
        SelectionMode | None,
        Field(
            description="How the platform uses repetitions of this group. 'sequential' means all items display in order (carousels, playlists). 'optimize' means the platform selects the best-performing combination from alternatives (asset group optimization like Meta Advantage+ or Google Pmax)."
        ),
    ] = SelectionMode.sequential
    assets: Annotated[
        list[Assets30], Field(description='Assets within each repetition of this group')
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

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

Inherited members

class Assets31 (**data: Any)
Expand source code
class Assets31(BaseGroupAsset):
    asset_type: Literal['image'] = 'image'
    requirements: image_asset_requirements.ImageAssetRequirements | 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 asset_type : Literal['image']
var model_config
var requirements : ImageAssetRequirements | None

Inherited members

class Assets32 (**data: Any)
Expand source code
class Assets32(BaseGroupAsset):
    asset_type: Literal['video'] = 'video'
    requirements: video_asset_requirements.VideoAssetRequirements | 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 asset_type : Literal['video']
var model_config
var requirements : VideoAssetRequirements | None

Inherited members

class Assets33 (**data: Any)
Expand source code
class Assets33(BaseGroupAsset):
    asset_type: Literal['audio'] = 'audio'
    requirements: audio_asset_requirements.AudioAssetRequirements | 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 asset_type : Literal['audio']
var model_config
var requirements : AudioAssetRequirements | None

Inherited members

class Assets34 (**data: Any)
Expand source code
class Assets34(BaseGroupAsset):
    asset_type: Literal['text'] = 'text'
    requirements: text_asset_requirements.TextAssetRequirements | 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 asset_type : Literal['text']
var model_config
var requirements : TextAssetRequirements | None

Inherited members

class Assets35 (**data: Any)
Expand source code
class Assets35(BaseGroupAsset):
    asset_type: Literal['markdown'] = 'markdown'
    requirements: markdown_asset_requirements.MarkdownAssetRequirements | 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 asset_type : Literal['markdown']
var model_config
var requirements : MarkdownAssetRequirements | None

Inherited members

class Assets36 (**data: Any)
Expand source code
class Assets36(BaseGroupAsset):
    asset_type: Literal['html'] = 'html'
    requirements: html_asset_requirements.HtmlAssetRequirements | 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 asset_type : Literal['html']
var model_config
var requirements : HtmlAssetRequirements | None

Inherited members

class Assets37 (**data: Any)
Expand source code
class Assets37(BaseGroupAsset):
    asset_type: Literal['css'] = 'css'
    requirements: css_asset_requirements.CssAssetRequirements | 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 asset_type : Literal['css']
var model_config
var requirements : CssAssetRequirements | None

Inherited members

class Assets38 (**data: Any)
Expand source code
class Assets38(BaseGroupAsset):
    asset_type: Literal['javascript'] = 'javascript'
    requirements: javascript_asset_requirements.JavascriptAssetRequirements | 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 asset_type : Literal['javascript']
var model_config
var requirements : JavascriptAssetRequirements | None

Inherited members

class Assets39 (**data: Any)
Expand source code
class Assets39(BaseGroupAsset):
    asset_type: Literal['zip'] = 'zip'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['zip']
var model_config

Inherited members

class Assets40 (**data: Any)
Expand source code
class Assets40(BaseGroupAsset):
    asset_type: Literal['vast'] = 'vast'
    requirements: vast_asset_requirements.VastAssetRequirements | 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 asset_type : Literal['vast']
var model_config
var requirements : VastAssetRequirements | None

Inherited members

class Assets41 (**data: Any)
Expand source code
class Assets41(BaseGroupAsset):
    asset_type: Literal['daast'] = 'daast'
    requirements: daast_asset_requirements.DaastAssetRequirements | 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 asset_type : Literal['daast']
var model_config
var requirements : DaastAssetRequirements | None

Inherited members

class Assets42 (**data: Any)
Expand source code
class Assets42(BaseGroupAsset):
    asset_type: Literal['url'] = 'url'
    requirements: url_asset_requirements.UrlAssetRequirements | 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 asset_type : Literal['url']
var model_config
var requirements : UrlAssetRequirements | None

Inherited members

class Assets43 (**data: Any)
Expand source code
class Assets43(BaseGroupAsset):
    asset_type: Literal['webhook'] = 'webhook'
    requirements: webhook_asset_requirements.WebhookAssetRequirements | 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 asset_type : Literal['webhook']
var model_config
var requirements : WebhookAssetRequirements | None

Inherited members

class Assets44 (**data: Any)
Expand source code
class Assets44(BaseGroupAsset):
    asset_type: Literal['brief'] = 'brief'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['brief']
var model_config

Inherited members

class Assets45 (**data: Any)
Expand source code
class Assets45(BaseGroupAsset):
    asset_type: Literal['catalog'] = 'catalog'
    requirements: catalog_requirements.CatalogRequirements | 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 asset_type : Literal['adcp.types.domains.core.catalog']
var model_config
var requirements : CatalogRequirements | None

Inherited members

class Assets46 (**data: Any)
Expand source code
class Assets46(BaseGroupAsset):
    asset_type: Literal['display_tag'] = '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 asset_type : Literal['display_tag']
var model_config

Inherited members

class Assets47 (**data: Any)
Expand source code
class Assets47(BaseGroupAsset):
    asset_type: Literal['published_post'] = 'published_post'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['published_post']
var model_config

Inherited members

class Assets48 (**data: Any)
Expand source code
class Assets48(BaseGroupAsset):
    asset_type: Literal['card'] = 'card'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['card']
var model_config

Inherited members

class Assets49 (**data: Any)
Expand source code
class Assets49(BaseGroupAsset):
    asset_type: Literal['pixel_tracker'] = 'pixel_tracker'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['pixel_tracker']
var model_config

Inherited members

class Assets50 (**data: Any)
Expand source code
class Assets50(BaseGroupAsset):
    asset_type: Literal['vast_tracker'] = 'vast_tracker'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['vast_tracker']
var model_config

Inherited members

class Assets51 (**data: Any)
Expand source code
class Assets51(BaseGroupAsset):
    asset_type: Literal['daast_tracker'] = 'daast_tracker'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['daast_tracker']
var model_config

Inherited members

class Assets9 (**data: Any)
Expand source code
class Assets9(BaseIndividualAsset):
    item_type: Literal['individual'] = 'individual'
    asset_type: Literal['video'] = 'video'
    requirements: video_asset_requirements.VideoAssetRequirements | 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 asset_type : Literal['video']
var item_type : Literal['individual']
var model_config
var requirements : VideoAssetRequirements | None

Inherited members

class AsyncAdcpVersion (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AsyncAdcpVersion(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^\\d+\\.\\d+$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class AttestationCapabilities (**data: Any)
Expand source code
class AttestationCapabilities(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    accepted_claim_types: Annotated[
        list[AnyUrl],
        Field(
            description='Open claim identifiers the evaluator is prepared to evaluate. Each value is an absolute URI. Absence means the evaluator has not advertised portable-attestation support; an empty list is not permitted.',
            min_length=1,
        ),
    ]
    accepted_proof_formats: Annotated[
        list[AnyUrl],
        Field(
            description='Open credential/proof format identifiers the evaluator can verify. Values are absolute URIs rather than a protocol enum so issuers can adopt new formats without AdCP endorsement.',
            min_length=1,
        ),
    ]
    supported_delivery_methods: Annotated[
        list[SupportedDeliveryMethod],
        Field(
            description='Credential delivery paths this evaluator supports. credential_uri resolves an HTTPS credential URI from the presentation; issuer_credential_id combines issuer, credential_id, and an evaluator-published resolver_id; embedded accepts an inline credential.',
            min_length=1,
        ),
    ]
    accepted_issuers: Annotated[
        list[AcceptedIssuer],
        Field(
            description='Issuer allowlist and resolver policy. Matching is on the canonical AttestationIssuer identity. A presenter-supplied issuer or credential URI that does not match this policy is rejected without an outbound request.',
            min_length=1,
        ),
    ]
    accepted_verifiers: Annotated[
        list[AcceptedVerifier] | None,
        Field(
            description="Verifier agents the evaluator may call. A presenter's verify_agent nomination must match one of these canonicalized URLs, but the evaluator remains verifier-of-record and chooses whether to use the nominated agent, another accepted agent, or local verification.",
            min_length=1,
        ),
    ] = None
    max_embedded_credential_bytes: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum UTF-8 byte size accepted for one embedded credential. Evaluators MUST enforce this limit before parsing the credential. The protocol ceiling is 1 MiB.',
            ge=1024,
            le=1048576,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 accepted_claim_types : list[pydantic.networks.AnyUrl]
var accepted_issuers : list[AcceptedIssuer]
var accepted_proof_formats : list[pydantic.networks.AnyUrl]
var accepted_verifiers : list[AcceptedVerifier] | None
var ext : ExtensionObject | None
var max_embedded_credential_bytes : int | None
var model_config
var supported_delivery_methods : list[SupportedDeliveryMethod]

Inherited members

class AttestationDigest (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AttestationDigest(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^sha256:[a-f0-9]{64}$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class AttestationIssuer1 (**data: Any)
Expand source code
class AttestationIssuer1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['brand'], Field(description='The issuer is identified by an AdCP BrandRef.')
    ] = 'brand'
    brand: brand_ref.BrandReference
    ext: ext_1.ExtensionObject | 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 brand : BrandReference
var ext : ExtensionObject | None
var model_config
var type : Literal['brand']

Inherited members

class AttestationIssuer2 (**data: Any)
Expand source code
class AttestationIssuer2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['agent'],
        Field(
            description='The issuer is an AdCP agent identified by its canonical HTTPS endpoint.'
        ),
    ] = 'agent'
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='Canonical HTTPS endpoint of the issuing agent. Evaluators compare it using AdCP URL canonicalization rules.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 agent_url : pydantic.networks.AnyUrl
var ext : ExtensionObject | None
var model_config
var type : Literal['agent']

Inherited members

class AttestationIssuer3 (**data: Any)
Expand source code
class AttestationIssuer3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['origin'],
        Field(
            description='The issuer is identified by a canonical HTTPS origin because no AdCP brand or agent identity applies.'
        ),
    ] = 'origin'
    origin: Annotated[
        AnyUrl,
        Field(
            description='Canonical HTTPS origin with no path, query, fragment, or userinfo. This identifies the issuer; it does not authorize a fetch.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var model_config
var origin : pydantic.networks.AnyUrl
var type : Literal['origin']

Inherited members

class AttestationReference (**data: Any)
Expand source code
class AttestationReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    issuer: attestation_issuer.AttestationIssuer
    claim_type: Annotated[
        AnyUrl,
        Field(
            description='Open, absolute URI identifying the claim vocabulary. The URI is an identifier and need not be dereferenceable. AdCP does not maintain an enum of approved claims.'
        ),
    ]
    subject: attestation_subject.AttestationSubject
    locator: Annotated[
        Locator | Locator1 | None,
        Field(
            description='Stable locator for resolving the credential. Credential URLs are permitted only when their canonical origin is allowlisted for the matched issuer. Issuer-scoped IDs name a resolver_id already published by the evaluator; the presentation cannot introduce a resolver URL.',
            discriminator='type',
        ),
    ] = None
    embedded_credential: Annotated[
        EmbeddedCredential | None,
        Field(
            description='Optional inline credential for private, authenticated, or offline delivery. It may accompany locator or be the only delivery path. Its format must be supported by the evaluator, and the evaluator MUST verify the credential exactly as it would a resolved credential.'
        ),
    ] = None
    content_digest: Annotated[
        str | None,
        Field(
            description='Optional SHA-256 digest pin for the exact credential bytes, formatted as sha256:<lowercase hex>. The credential format defines its canonical byte representation. A mismatch is invalid and MUST NOT fall back to the unpinned credential. REQUIRED when both locator and embedded_credential are present; both byte representations MUST match this digest.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    credential_version: Annotated[
        str | None,
        Field(
            description='Optional issuer-defined credential version hint. It is advisory; the resolved credential is authoritative.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    validity_hint: Annotated[
        ValidityHint | None,
        Field(
            description="Optional planning-time validity hint copied from issuer metadata. Evaluators MUST use the resolved or embedded credential's signed validity and revocation state as authoritative."
        ),
    ] = None
    verify_agent: Annotated[
        VerifyAgent | None,
        Field(
            description='Optional presenter nomination of a verifier already published by the evaluator. This is a representation, not routing authority: agent_url MUST match an accepted_verifiers[] entry after canonicalization, and the evaluator may choose another accepted verifier or verify locally.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None

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

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 claim_type : pydantic.networks.AnyUrl
var content_digest : str | None
var credential_version : str | None
var embedded_credential : EmbeddedCredential | None
var ext : ExtensionObject | None
var issuer : AttestationIssuer1 | AttestationIssuer2 | AttestationIssuer3
var locator : Locator | Locator1 | None
var model_config
var subject : AttestationSubject1 | AttestationSubject2 | AttestationSubject3
var validity_hint : ValidityHint | None
var verify_agent : VerifyAgent | None

Inherited members

class AttestationSubject1 (**data: Any)
Expand source code
class AttestationSubject1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['brand'] = 'brand'
    brand: brand_ref.BrandReference
    ext: ext_1.ExtensionObject | 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 brand : BrandReference
var ext : ExtensionObject | None
var model_config
var type : Literal['brand']

Inherited members

class AttestationSubject2 (**data: Any)
Expand source code
class AttestationSubject2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['agent'] = 'agent'
    agent_url: Annotated[
        AnyUrl, Field(description='Canonical HTTPS endpoint of the agent the claim concerns.')
    ]
    ext: ext_1.ExtensionObject | 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 agent_url : pydantic.networks.AnyUrl
var ext : ExtensionObject | None
var model_config
var type : Literal['agent']

Inherited members

class AttestationSubject3 (**data: Any)
Expand source code
class AttestationSubject3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['resource'] = 'resource'
    resource_type: Annotated[
        AnyUrl,
        Field(
            description='Open, absolute URI naming the subject vocabulary, such as https://adcontextprotocol.org/claims/subjects/signal. AdCP does not maintain an exhaustive enum.'
        ),
    ]
    namespace: Annotated[
        AnyUrl,
        Field(
            description='Absolute URI identifying the namespace in which id is unique. This may be an AdCP agent endpoint, a catalog origin, or a domain-specific namespace URI.'
        ),
    ]
    id: Annotated[
        str,
        Field(
            description='Stable identifier for the subject within namespace. It MUST NOT be compared without resource_type and namespace.',
            max_length=1024,
            min_length=1,
        ),
    ]
    content_digest: Annotated[
        str | None,
        Field(
            description='Optional SHA-256 pin for the exact content or immutable snapshot identified by this resource subject. This is part of the complete typed subject identity and is distinct from AttestationReference.content_digest, which pins credential bytes.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 content_digest : str | None
var ext : ExtensionObject | None
var id : str
var model_config
var namespace : pydantic.networks.AnyUrl
var resource_type : pydantic.networks.AnyUrl
var type : Literal['resource']

Inherited members

class AttributionWindow (**data: Any)
Expand source code
class AttributionWindow(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    post_click: Annotated[
        duration.Duration | None,
        Field(
            description='Post-click attribution window. Conversions occurring within this duration after a click are attributed to the ad.'
        ),
    ] = None
    post_view: Annotated[
        duration.Duration | None,
        Field(
            description='Post-view attribution window. Conversions occurring within this duration after an ad impression (without click) are attributed to the ad.'
        ),
    ] = None
    model: Annotated[
        attribution_model.AttributionModel | None,
        Field(
            description="Attribution model used to assign credit when multiple touchpoints exist. SHOULD be populated when committing to a specific model; when absent, the seller's default applies."
        ),
    ] = 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 model : AttributionModel | None
var model_config
var post_click : Duration | None
var post_view : Duration | None

Inherited members

class Audience (*args, **kwds)
Expand source code
class Audience(StrEnum):
    buyer = 'buyer'
    data_subject = 'data_subject'
    regulator = 'regulator'
    public = 'public'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var buyer
var data_subject
var public
var regulator
class AudienceActivation (**data: Any)
Expand source code
class AudienceActivation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    methods: Annotated[
        list[audience_activation_method.AudienceActivationMethod],
        Field(
            description='Activation capabilities available on this product, as an unordered set. Entries are usually independent options; a clean_room entry may compose with dataset_query or platform_distribution to declare how a targetable result leaves the room or reaches the buying platform.',
            min_length=1,
        ),
    ]
    preferred_method: Annotated[
        audience_activation_method.AudienceActivationMethod | None,
        Field(
            description="The seller's preferred path when the buyer supports several. MUST also appear in methods."
        ),
    ] = None
    notes: Annotated[
        str | None,
        Field(
            description='Free-text caveats (onboarding lead times, data-format constraints, regional restrictions).'
        ),
    ] = 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 methods : list[AudienceActivationMethod1 | AudienceActivationMethod2 | AudienceActivationMethod3 | AudienceActivationMethod4 | AudienceActivationMethod5 | AudienceActivationMethod6]
var model_config
var notes : str | None
var preferred_method : AudienceActivationMethod1 | AudienceActivationMethod2 | AudienceActivationMethod3 | AudienceActivationMethod4 | AudienceActivationMethod5 | AudienceActivationMethod6 | None

Inherited members

class AudienceActivationMethod1 (**data: Any)
Expand source code
class AudienceActivationMethod1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['sync_audiences'] = 'sync_audiences'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var pattern : Literal['sync_audiences']

Inherited members

class AudienceActivationMethod2 (**data: Any)
Expand source code
class AudienceActivationMethod2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['tmp_identity_match'] = 'tmp_identity_match'
    buyer_agent: BuyerAgent

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 buyer_agent : BuyerAgent
var model_config
var pattern : Literal['tmp_identity_match']

Inherited members

class AudienceActivationMethod3 (**data: Any)
Expand source code
class AudienceActivationMethod3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['file_transfer'] = 'file_transfer'
    transport: Annotated[
        cloud_storage_protocol.CloudStorageProtocol,
        Field(description='Storage protocol for the exchange.'),
    ]
    directions: Annotated[
        list[Direction] | None,
        Field(
            description='Supported transfer directions. buyer_to_seller: buyer writes to a seller-hosted bucket. seller_to_buyer: seller reads from a buyer-hosted bucket. Absent means unspecified (resolve during account setup), not neither.',
            min_length=1,
        ),
    ] = None
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description="Platform providing the storage primitive (e.g., the cloud provider's domain)."
        ),
    ]

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 directions : list[Direction] | None
var model_config
var pattern : Literal['file_transfer']
var transport : CloudStorageProtocol
var vendor : BrandReference

Inherited members

class AudienceActivationMethod4 (**data: Any)
Expand source code
class AudienceActivationMethod4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['dataset_query'] = 'dataset_query'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(description='Data-sharing platform the seller can consume from.'),
    ]
    consumer_identities: Annotated[
        list[ConsumerIdentity] | None,
        Field(
            description="Principals the buyer grants access to in the vendor's system. identity is always required. cloud and region are optional, paired deployment metadata: omit both for global principals (for example, an IAM principal or federated identity). Their operational meaning is vendor-specific — they may constrain direct-share reachability or select a fulfillment route, or may be routing and cost hints only. They are not compliance boundaries; data-transfer assessments key on the recipient entity's jurisdiction, not the grantee account's region. Optional: sellers MAY instead communicate identities during account setup.",
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var consumer_identities : list[ConsumerIdentity] | None
var model_config
var pattern : Literal['dataset_query']
var vendor : BrandReference

Inherited members

class AudienceActivationMethod5 (**data: Any)
Expand source code
class AudienceActivationMethod5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['clean_room'] = 'clean_room'
    vendor: Annotated[
        brand_ref.BrandReference, Field(description="Clean-room product's operating domain.")
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var pattern : Literal['clean_room']
var vendor : BrandReference

Inherited members

class AudienceActivationMethod6 (**data: Any)
Expand source code
class AudienceActivationMethod6(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['platform_distribution'] = 'platform_distribution'
    vendor: Annotated[
        brand_ref.BrandReference, Field(description="Distribution platform's operating domain.")
    ]
    destination_ref: Annotated[
        str | None,
        Field(
            description="Opaque, account-scoped destination or seat reference in the vendor's system, as the buyer needs it to initiate distribution. A seller-declared configuration reference, not a buyer-invoked key or secret. Sellers MUST NOT publish one global reference when the vendor configuration is buyer- or account-specific. Omit until account setup has established the destination.",
            max_length=256,
            min_length=1,
        ),
    ] = None
    bind_expiry_days: Annotated[
        SchemaInt | None,
        Field(
            description="Window after which the seller MAY expire an unfulfilled platform_segment bind (per-audience action: failed on sync_audiences). Initial vendor distribution is days-scale; windows shorter than the vendor's documented distribution latency are non-conformant.",
            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

Class variables

var bind_expiry_days : int | None
var destination_ref : str | None
var model_config
var pattern : Literal['platform_distribution']
var vendor : BrandReference

Inherited members

class AudienceActivationMethods (**data: Any)
Expand source code
class AudienceActivationMethods(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['sync_audiences'] = 'sync_audiences'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var pattern : Literal['sync_audiences']

Inherited members

class AudienceActivationMethods1 (**data: Any)
Expand source code
class AudienceActivationMethods1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['tmp_identity_match'] = 'tmp_identity_match'
    buyer_agent: Annotated[
        BuyerAgent | None,
        Field(
            description='Require this buyer agent on tmp_identity_match entries. Buyers typically filter on their own agent_url.'
        ),
    ] = 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 buyer_agent : BuyerAgent | None
var model_config
var pattern : Literal['tmp_identity_match']

Inherited members

class AudienceActivationMethods2 (**data: Any)
Expand source code
class AudienceActivationMethods2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['file_transfer'] = 'file_transfer'
    transport: Annotated[
        cloud_storage_protocol.CloudStorageProtocol | None,
        Field(description='Require this storage protocol (file_transfer only).'),
    ] = None
    directions: Annotated[
        list[Direction] | None,
        Field(
            description="Require a non-empty intersection with the method's declared directions (file_transfer only).",
            min_length=1,
        ),
    ] = None
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(description="Require the method's vendor to match this reference."),
    ] = 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 directions : list[Direction] | None
var model_config
var pattern : Literal['file_transfer']
var transport : CloudStorageProtocol | None
var vendor : BrandReference | None

Inherited members

class AudienceActivationMethods3 (**data: Any)
Expand source code
class AudienceActivationMethods3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['dataset_query'] = 'dataset_query'
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(description="Require the method's vendor to match this reference."),
    ] = 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 model_config
var pattern : Literal['dataset_query']
var vendor : BrandReference | None

Inherited members

class AudienceActivationMethods4 (**data: Any)
Expand source code
class AudienceActivationMethods4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['clean_room'] = 'clean_room'
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(description="Require the method's vendor to match this reference."),
    ] = 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 model_config
var pattern : Literal['clean_room']
var vendor : BrandReference | None

Inherited members

class AudienceActivationMethods5 (**data: Any)
Expand source code
class AudienceActivationMethods5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Literal['platform_distribution'] = 'platform_distribution'
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(description="Require the method's vendor to match this reference."),
    ] = 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 model_config
var pattern : Literal['platform_distribution']
var vendor : BrandReference | None

Inherited members

class AudienceCharacteristic (**data: Any)
Expand source code
class AudienceCharacteristic(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    dimension: Annotated[
        Literal['age'] | Dimension,
        Field(
            description='Canonical dimension name or HTTPS URI. AdCP 3.2 defines `age`; other values remain provider- or taxonomy-scoped.'
        ),
    ]
    value: Annotated[
        str | StrictFloat | StrictBool | Value | None,
        Field(description='Scalar or set value for the dimension.'),
    ] = None
    range: Annotated[
        Range | None,
        Field(
            description='Inclusive numeric interval. For dimension `age`, values are completed years and MUST be non-negative integers, and min MUST be less than or equal to max. JSON Schema enforces the age value and bound types; implementations enforce the relational min <= max constraint.'
        ),
    ] = None
    taxonomy: Annotated[
        Taxonomy | None,
        Field(
            description='External system that defines the dimension or value. Taxonomy metadata is descriptive and does not create exact demographic targeting semantics.'
        ),
    ] = None
    label: Annotated[
        str | None, Field(description='Human-readable display label; never the comparison key.')
    ] = None

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

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 dimension : Literal['age'] | Dimension
var label : str | None
var model_config
var range : Range | None
var taxonomy : Taxonomy | None
var value : str | float | bool | Value | None

Inherited members

class AudienceEvidence (**data: Any)
Expand source code
class AudienceEvidence(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    evidence_id: Annotated[
        str,
        Field(
            description='Stable provider-scoped identifier for the logical evidence series across versions.',
            min_length=1,
        ),
    ]
    snapshot_id: Annotated[
        str,
        Field(
            description='Seller-scoped immutable snapshot identifier. It MUST never be reused for different content.',
            min_length=1,
        ),
    ]
    version: Annotated[
        str, Field(description='Provider version of this evidence snapshot.', min_length=1)
    ]
    content_digest: Annotated[
        str,
        Field(
            description='SHA-256 of the RFC 8785 (JCS) canonical evidence core with content_digest and attestation_refs omitted. Attestation references are excluded so independently issued credentials can be attached without changing the immutable evidence snapshot and without creating a recursive digest. This digest is required even when snapshot_id is present so buyers can detect identifier reuse or catalog drift.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    audience: audience_characteristic.AudienceCharacteristic
    relationship: Annotated[
        Relationship,
        Field(
            description='What the estimate says: population share, ratio to a baseline, or estimated reachable count.'
        ),
    ]
    value: Annotated[
        StrictFloat,
        Field(description='Estimated relationship value, interpreted according to unit.', ge=0.0),
    ]
    unit: Annotated[
        Unit,
        Field(
            description='composition uses fraction in [0,1], index uses ratio, and reach_estimate uses count.'
        ),
    ]
    baseline: Annotated[
        Baseline,
        Field(description='Reference population against which the estimate was calculated.'),
    ]
    evidence_type: Annotated[
        EvidenceType,
        Field(
            description='Nature of the evidence. Independent verification is represented separately by attestation_refs and never inferred from this value.'
        ),
    ]
    methodology: audience_evidence_methodology.AudienceEvidenceMethodology
    subject_type: audience_subject_type.AudienceSubjectType
    resolution_method: Annotated[
        audience_resolution_method.AudienceResolutionMethod | None,
        Field(
            description='Optional subject-resolution method used by the study or estimate. This describes population methodology, not a promise that the product can execute that resolution at serving time.'
        ),
    ] = None
    provider: Annotated[
        brand_ref.BrandReference, Field(description='Brand responsible for producing the evidence.')
    ]
    measurement_window: date_range.DateRange
    sample_size: Annotated[
        SchemaInt | None,
        Field(
            description='Number of observations or respondents underlying the estimate, when applicable.',
            ge=1,
        ),
    ] = None
    confidence: Annotated[
        StrictFloat | None,
        Field(
            description="Provider-defined confidence score in [0,1]. Consumers MUST compare scores only when the provider's methodology makes them comparable.",
            ge=0.0,
            le=1.0,
        ),
    ] = None
    last_updated: Annotated[
        AwareDatetime,
        Field(description='When the provider last produced or refreshed this immutable snapshot.'),
    ]
    methodology_url: Annotated[
        AnyUrl | None,
        Field(
            description='Documentation for interpreting the methodology. It is disclosure, not executable routing.'
        ),
    ] = None
    attestation_refs: Annotated[
        list[AttestationRef] | None,
        Field(
            description="Optional portable attestations about this exact evidence snapshot. Each subject MUST be resource type https://adcontextprotocol.org/claims/subjects/audience-evidence, subject.id MUST equal snapshot_id, and subject.content_digest MUST equal this evidence object's content_digest. Buyer references do not override evaluator issuer or resolver policy.",
            max_length=10,
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 attestation_refs : list[AttestationRef] | None
var audience : AudienceCharacteristic
var baseline : Baseline
var confidence : float | None
var content_digest : str
var evidence_id : str
var evidence_type : EvidenceType
var ext : ExtensionObject | None
var last_updated : pydantic.types.AwareDatetime
var measurement_window : DateRange
var methodology : AudienceEvidenceMethodology
var methodology_url : pydantic.networks.AnyUrl | None
var model_config
var provider : BrandReference
var relationship : Relationship
var resolution_method : AudienceResolutionMethod | None
var sample_size : int | None
var snapshot_id : str
var subject_type : AudienceSubjectType
var unit : Unit
var value : float
var version : str

Inherited members

class AudienceEvidencePin (**data: Any)
Expand source code
class AudienceEvidencePin(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    evidence_id: Annotated[str, Field(min_length=1)]
    snapshot_id: Annotated[str, Field(min_length=1)]
    version: Annotated[str, Field(min_length=1)]
    content_digest: Annotated[str, Field(pattern='^sha256:[a-f0-9]{64}$')]
    ext: ext_1.ExtensionObject | 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 content_digest : str
var evidence_id : str
var ext : ExtensionObject | None
var model_config
var snapshot_id : str
var version : str

Inherited members

class AudienceEvidenceRequirements (**data: Any)
Expand source code
class AudienceEvidenceRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    requirement_mode: Annotated[
        RequirementMode,
        Field(
            description='required excludes products whose published evidence violates the constraints; preferred only affects ranking and explanation. When this policy affects inclusion or ranking, the seller MUST return the exact matching audience_evidence_selections even if get_products.fields omitted that field.'
        ),
    ]
    evidence_presence: Annotated[
        EvidencePresence,
        Field(
            description='required applies the mode to evidence presence itself. when_available applies constraints only when a product publishes evidence: with requirement_mode required, a product with no evidence remains eligible but a product with evidence must have an admissible item; with preferred, presence and admissibility only affect ranking.'
        ),
    ]
    accepted_methodologies: Annotated[
        list[audience_evidence_methodology.AudienceEvidenceMethodology] | None,
        Field(
            description='Allowed methodologies. excluded_methodologies always wins if a value appears in both lists.',
            min_length=1,
        ),
    ] = None
    excluded_methodologies: Annotated[
        list[audience_evidence_methodology.AudienceEvidenceMethodology] | None,
        Field(
            description='Disallowed methodologies. Exclusion wins over accepted_methodologies when the lists overlap.',
            min_length=1,
        ),
    ] = None
    accepted_evidence_types: Annotated[list[AcceptedEvidenceType] | None, Field(min_length=1)] = (
        None
    )
    accepted_providers: Annotated[
        list[brand_ref.BrandReference] | None,
        Field(
            description='Allowed evidence providers. excluded_providers always wins if the same canonical BrandRef appears in both lists.',
            min_length=1,
        ),
    ] = None
    excluded_providers: Annotated[
        list[brand_ref.BrandReference] | None,
        Field(
            description='Disallowed evidence providers. Exclusion wins over accepted_providers when the lists overlap.',
            min_length=1,
        ),
    ] = None
    accepted_subject_types: Annotated[
        list[audience_subject_type.AudienceSubjectType] | None, Field(min_length=1)
    ] = None
    accepted_resolution_methods: Annotated[
        list[audience_resolution_method.AudienceResolutionMethod] | None, Field(min_length=1)
    ] = None
    minimum_confidence: Annotated[StrictFloat | None, Field(ge=0.0, le=1.0)] = None
    maximum_age: Annotated[
        MaximumAge | None,
        Field(
            description='Maximum age at evaluation time measured from last_updated. Campaign-relative duration is not valid for evidence age.'
        ),
    ] = None
    methodology_documentation_required: Annotated[
        StrictBool | None,
        Field(description='Whether an admissible item must carry methodology_url.'),
    ] = False
    independent_attestation_required: Annotated[
        StrictBool | None,
        Field(
            description="Whether an admissible item must have at least one exact reference/evaluation pair whose outcome is verified, whose reference is published in the evidence, and whose claim type and issuer match the buyer's accepted lists as well as the seller's issuer and resolver policy. Setting true requires accepted_attestation_issuers."
        ),
    ] = False
    accepted_attestation_issuers: Annotated[
        list[attestation_issuer.AttestationIssuer] | None,
        Field(
            description="Buyer allowlist for independent attestation issuers. An exact reference/evaluation pair satisfies the requirement only when reference.issuer matches an entry here. This list narrows and never broadens the seller's accepted issuer policy.",
            min_length=1,
        ),
    ] = None
    accepted_attestation_claim_types: Annotated[
        list[AnyUrl] | None,
        Field(
            description='Optional acceptable claim types when attestation is used. Buyer-supplied claim types further constrain but never broaden seller policy.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 accepted_attestation_claim_types : list[pydantic.networks.AnyUrl] | None
var accepted_attestation_issuers : list[AttestationIssuer1 | AttestationIssuer2 | AttestationIssuer3] | None
var accepted_evidence_types : list[AcceptedEvidenceType] | None
var accepted_methodologies : list[AudienceEvidenceMethodology] | None
var accepted_providers : list[BrandReference] | None
var accepted_resolution_methods : list[AudienceResolutionMethod] | None
var accepted_subject_types : list[AudienceSubjectType] | None
var evidence_presence : EvidencePresence
var excluded_methodologies : list[AudienceEvidenceMethodology] | None
var excluded_providers : list[BrandReference] | None
var ext : ExtensionObject | None
var independent_attestation_required : bool | None
var maximum_age : MaximumAge | None
var methodology_documentation_required : bool | None
var minimum_confidence : float | None
var model_config
var requirement_mode : RequirementMode

Inherited members

class AudienceEvidenceSelection (**data: Any)
Expand source code
class AudienceEvidenceSelection(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    evidence_id: Annotated[str, Field(min_length=1)]
    snapshot_id: Annotated[str, Field(min_length=1)]
    version: Annotated[str, Field(min_length=1)]
    content_digest: Annotated[str, Field(pattern='^sha256:[a-f0-9]{64}$')]
    decision_use: Annotated[
        DecisionUse,
        Field(
            description="How this evidence affected the seller's decision. This is not targeting execution."
        ),
    ]
    evidence: Annotated[
        audience_evidence.AudienceEvidence | None,
        Field(
            description='Optional inline immutable snapshot. Its identity, version, and digest MUST equal the surrounding fields.'
        ),
    ] = None
    attestation_evaluations: Annotated[
        list[AttestationEvaluation] | None,
        Field(
            description="Exact reference/evaluation pairs used in the decision. The reference MUST be one of the selected evidence snapshot's attestation_refs, evaluation.reference_digest MUST equal the digest of that same reference, reference.subject.content_digest and evaluation.action_binding.action_digest MUST equal this selection's content_digest, evaluation.action_binding.action_id MUST equal snapshot_id, and action_type MUST be https://adcontextprotocol.org/actions/audience-evidence-evaluation.",
            max_length=10,
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 attestation_evaluations : list[AttestationEvaluation] | None
var content_digest : str
var decision_use : DecisionUse
var evidence : AudienceEvidence | None
var evidence_id : str
var ext : ExtensionObject | None
var model_config
var snapshot_id : str
var version : str

Inherited members

class AudienceForecastDimension (**data: Any)
Expand source code
class AudienceForecastDimension(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Annotated[Literal['audience'], Field(description='Dimension family discriminator.')] = 'audience'
    audience_id: Annotated[
        str, Field(description='Audience segment identifier for this forecast row.')
    ]
    audience_source: Annotated[
        audience_source_1.AudienceSource, Field(description='Origin of the audience segment.')
    ]
    audience_name: Annotated[
        str | None, Field(description='Human-readable audience segment name.')
    ] = 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 audience_id : str
var audience_name : str | None
var audience_source : AudienceSource
var kind : Literal['audience']
var model_config

Inherited members

class AudienceMember (**data: Any)
Expand source code
class AudienceMember(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    external_id: Annotated[
        str,
        Field(
            description="Buyer-assigned stable identifier for this audience member (e.g. CRM record ID, loyalty ID). Used for deduplication, removal, and cross-referencing with buyer systems. Adapters for CDPs that don't natively assign IDs can derive one (e.g. hash of the member's identifiers)."
        ),
    ]
    hashed_email: Annotated[
        str | None,
        Field(
            description='SHA-256 hash of lowercase, trimmed email address. Pseudonymous PII, not anonymous — the email namespace is small enough that an unsalted SHA-256 is recoverable via precomputed dictionaries. Treat as PII for retention, consent, and access-control purposes. See docs/reference/privacy-considerations#unsalted-hashed-identifiers-are-pseudonymous-not-anonymous.',
            pattern='^[a-f0-9]{64}$',
        ),
    ] = None
    hashed_phone: Annotated[
        str | None,
        Field(
            description='SHA-256 hash of E.164-formatted phone number (e.g. +12065551234). Pseudonymous PII, not anonymous — the E.164 namespace is small enough that an unsalted SHA-256 is recoverable via precomputed dictionaries. Treat as PII for retention, consent, and access-control purposes. See docs/reference/privacy-considerations#unsalted-hashed-identifiers-are-pseudonymous-not-anonymous.',
            pattern='^[a-f0-9]{64}$',
        ),
    ] = None
    uids: Annotated[
        list[Uid] | None,
        Field(
            description='Universal ID values (MAIDs, RampID, UID2, etc.) for user matching.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None

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

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 ext : ExtensionObject | None
var external_id : str
var hashed_email : str | None
var hashed_phone : str | None
var model_config
var uids : list[Uid] | None

Inherited members

class AudienceScope (*args, **kwds)
Expand source code
class AudienceScope(StrEnum):
    single_domain = 'single_domain'
    cross_domain_owned = 'cross_domain_owned'
    cross_domain_unowned = 'cross_domain_unowned'
    offline = 'offline'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var cross_domain_owned
var cross_domain_unowned
var offline
var single_domain
class AudienceSelector1 (**data: Any)
Expand source code
class AudienceSelector1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['signal'], Field(description='Discriminator for signal-based selectors')
    ] = 'signal'
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New selectors SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[Literal['binary'], Field(description='Discriminator for binary signals')] = 'binary'
    value: Annotated[
        StrictBool,
        Field(
            description='Whether to include (true) or exclude (false) users matching this signal'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var type : Literal['signal']
var value : bool
var value_type : Literal['binary']

Inherited members

class AudienceSelector2 (**data: Any)
Expand source code
class AudienceSelector2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['signal'], Field(description='Discriminator for signal-based selectors')
    ] = 'signal'
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New selectors SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[
        Literal['categorical'], Field(description='Discriminator for categorical signals')
    ] = 'categorical'
    values: Annotated[
        list[str],
        Field(
            description='Values to target. Users with any of these values will be included.',
            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 model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var type : Literal['signal']
var value_type : Literal['categorical']
var values : list[str]

Inherited members

class AudienceSelector3 (**data: Any)
Expand source code
class AudienceSelector3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['signal'], Field(description='Discriminator for signal-based selectors')
    ] = 'signal'
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New selectors SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[
        Literal['numeric'], Field(description='Discriminator for numeric signals')
    ] = 'numeric'
    min_value: Annotated[
        StrictFloat | None,
        Field(
            description='Minimum value (inclusive). Omit for no minimum. Must be <= max_value when both are provided.'
        ),
    ] = None
    max_value: Annotated[
        StrictFloat | None,
        Field(
            description='Maximum value (inclusive). Omit for no maximum. Must be >= min_value when both are provided.'
        ),
    ] = 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 max_value : float | None
var min_value : float | None
var model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var type : Literal['signal']
var value_type : Literal['numeric']

Inherited members

class AudienceSelector4 (**data: Any)
Expand source code
class AudienceSelector4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['description'], Field(description='Discriminator for description-based selectors')
    ] = 'description'
    description: Annotated[
        str,
        Field(
            description="Natural language description of the audience (e.g., 'likely EV buyers', 'high net worth individuals', 'vulnerable communities')",
            max_length=2000,
            min_length=1,
        ),
    ]
    category: Annotated[
        str | None,
        Field(
            description="Optional grouping hint for the governance agent (e.g., 'demographic', 'behavioral', 'contextual', 'financial')"
        ),
    ] = 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 category : str | None
var description : str
var model_config
var type : Literal['description']

Inherited members

class AudienceSource1 (**data: Any)
Expand source code
class AudienceSource1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['dataset'] = 'dataset'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(description='Data-sharing platform hosting the shared object.'),
    ]
    locator: Annotated[
        str,
        Field(
            description="Vendor-native reference to the shared object (share/database/table path). Opaque to AdCP; meaningful to the vendor. Never a credential. For the Databricks path, the locator convention is share://<provider-sharing-identifier>/<share-name>/<schema>.<object>; this identifies what to read and is distinct from the seller's recipient identity in consumer_identities[].",
            max_length=512,
            min_length=1,
        ),
    ]
    access_expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='ISO 8601 time after which the buyer will revoke the grant. Declarative — tells the seller when the pipe closes so re-read behavior is predictable. Expiry bounds the access window, not retention: revocation does not claw back matched membership, and retention remains governed by the buyer-seller data processing agreement.'
        ),
    ] = 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 access_expires_at : pydantic.types.AwareDatetime | None
var kind : Literal['dataset']
var locator : str
var model_config
var vendor : BrandReference

Inherited members

class AudienceSource2 (**data: Any)
Expand source code
class AudienceSource2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['platform_segment'] = 'platform_segment'
    vendor: Annotated[
        brand_ref.BrandReference, Field(description='Distribution platform delivering the segment.')
    ]
    segment_ref: Annotated[
        str,
        Field(
            description="The vendor's segment identifier as issued to the buyer (the ID observable in the vendor's console/API). The seller owns the mapping to whatever identifier its ingest minted — it configured the destination and is the only party that can see both sides.",
            max_length=256,
            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 kind : Literal['platform_segment']
var model_config
var segment_ref : str
var vendor : BrandReference

Inherited members

class AudioAssetRequirements (**data: Any)
Expand source code
class AudioAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    min_duration_ms: Annotated[
        SchemaInt | None, Field(description='Minimum duration in milliseconds', ge=1)
    ] = None
    max_duration_ms: Annotated[
        SchemaInt | None, Field(description='Maximum duration in milliseconds', ge=1)
    ] = None
    formats: Annotated[list[Format] | None, Field(description='Accepted audio file formats')] = None
    max_file_size_kb: Annotated[
        SchemaInt | None, Field(description='Maximum file size in kilobytes', ge=1)
    ] = None
    sample_rates: Annotated[
        list[SampleRate] | None,
        Field(description='Accepted sample rates in Hz (e.g., [44100, 48000])'),
    ] = None
    channels: Annotated[
        list[Channel] | None, Field(description='Accepted audio channel configurations')
    ] = None
    min_bitrate_kbps: Annotated[
        SchemaInt | None, Field(description='Minimum audio bitrate in kilobits per second', ge=1)
    ] = None
    max_bitrate_kbps: Annotated[
        SchemaInt | None, Field(description='Maximum audio bitrate in kilobits per second', ge=1)
    ] = None
    loudness_lufs: Annotated[
        StrictFloat | None,
        Field(
            description='Target integrated loudness in LUFS. LKFS is the equivalent unit name under ITU-R BS.1770; values expressed in LUFS and LKFS are directly comparable without conversion.'
        ),
    ] = None
    loudness_tolerance_db: Annotated[
        StrictFloat | None,
        Field(description='Acceptable deviation from the loudness_lufs target in dB.', ge=0.0),
    ] = None
    true_peak_dbfs: Annotated[
        StrictFloat | None, Field(description='Maximum true-peak level in dBFS.')
    ] = 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 channels : list[Channel] | None
var formats : list[Format] | None
var loudness_lufs : float | None
var loudness_tolerance_db : float | None
var max_bitrate_kbps : int | None
var max_duration_ms : int | None
var max_file_size_kb : int | None
var min_bitrate_kbps : int | None
var min_duration_ms : int | None
var model_config
var sample_rates : list[SampleRate] | None
var true_peak_dbfs : float | None

Inherited members

class AudioChannelLayout (*args, **kwds)
Expand source code
class AudioChannelLayout(StrEnum):
    mono = 'mono'
    stereo = 'stereo'
    field_5_1 = '5.1'
    field_7_1 = '7.1'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var field_5_1
var field_7_1
var mono
var stereo
class AudioCodec (*args, **kwds)
Expand source code
class AudioCodec(StrEnum):
    aac = 'aac'
    pcm = 'pcm'
    ac3 = 'ac3'
    eac3 = 'eac3'
    mp3 = 'mp3'
    opus = 'opus'
    vorbis = 'vorbis'
    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 ac3
var eac3
var flac
var mp3
var opus
var pcm
var vorbis
class AudioSampleRate (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class AudioSampleRate(ScalarInt):
    __slots__ = ()
    _constraints = {'ge': 1}

An int generated from a JSON Schema integer root.

Validates the way SchemaInt validates an integer field: strict, so "1" and True are refused, with a float carrying no fractional part narrowed to int because JSON Schema counts it as one.

Ancestors

  • adcp.types._scalar.ScalarInt
  • adcp.types._scalar._ScalarRoot
  • builtins.int
class Auth (*args, **kwds)
Expand source code
class Auth(StrEnum):
    none = 'none'
    seller_credentials = 'seller_credentials'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var none
var seller_credentials
class AuthoritativeParty (*args, **kwds)
Expand source code
class AuthoritativeParty(StrEnum):
    seller = 'seller'
    consumer = 'consumer'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var consumer
var seller
class AuthorizationPayload (**data: Any)
Expand source code
class AuthorizationPayload(Payload12):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class AuthorizationType (*args, **kwds)
Expand source code
class AuthorizationType(StrEnum):
    property_ids = 'property_ids'
    property_tags = 'property_tags'
    inline_properties = 'inline_properties'
    publisher_properties = 'publisher_properties'
    signal_ids = 'signal_ids'
    signal_tags = 'signal_tags'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var inline_properties
var property_ids
var property_tags
var publisher_properties
var signal_ids
var signal_tags
class AuthorizedAgentBaseFields (**data: Any)
Expand source code
class AuthorizedAgentBaseFields(AdCPBaseModel):
    url: Annotated[
        AnyUrl,
        Field(
            description="The authorized agent's API endpoint URL. Callers comparing this URL against a registry (sales-agent list, signal-provider registry, TMP provider lookup, etc.) MUST canonicalize both sides per the AdCP URL canonicalization rules, not byte-equality — two URLs that differ only in case, default port, or percent-encoding of unreserved characters are the same agent. See docs/reference/url-canonicalization."
        ),
    ]
    authorized_for: Annotated[
        str,
        Field(
            description='Human-readable description of what this agent is authorized to do — what it sells (for sales/property agents) or what data it provides (for signal agents). The variant the entry uses (`property_ids`, `signal_tags`, etc.) tells consumers which inflection applies; this field carries the operator-supplied label.',
            max_length=500,
            min_length=1,
        ),
    ]
    signing_keys: Annotated[
        list[agent_signing_key.AgentSigningKey] | None,
        Field(
            description='Optional publisher-attested public signing keys for this agent. Use these as the trust anchor for verifying signed agent responses instead of relying on key discovery from the agent domain alone.',
            min_length=1,
        ),
    ] = None
    encryption_keys: Annotated[
        list[agent_encryption_key.AgentEncryptionKey] | None,
        Field(
            description='X25519 public keys for TMPX exposure token encryption. Each key identifies a cluster master that can decrypt TMPX tokens. Used with HPKE mode_base — read replicas encrypt with this public key, only the master can decrypt.',
            min_length=1,
        ),
    ] = None
    last_updated: Annotated[
        AwareDatetime | None,
        Field(
            description='Optional ISO 8601 timestamp indicating when this `authorized_agents[]` entry last changed. Independent of the file-level `last_updated`. Lets validators perform a partial walk by skipping entries whose `last_updated` is older than their indexed value. Advisory — consumers MAY ignore and re-index the full file.'
        ),
    ] = 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 authorized_for : str
var encryption_keys : list[AgentEncryptionKey] | None
var last_updated : pydantic.types.AwareDatetime | None
var model_config
var signing_keys : list[AgentSigningKey] | None
var url : pydantic.networks.AnyUrl

Inherited members

class AvailabilityHorizon (**data: Any)
Expand source code
class AvailabilityHorizon(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    start_time: Annotated[
        AwareDatetime,
        Field(description='Inclusive horizon start (RFC 3339 date-time with timezone offset).'),
    ]
    end_time: Annotated[
        AwareDatetime,
        Field(
            description='Exclusive horizon end (RFC 3339 date-time with timezone offset). MUST be after start_time.'
        ),
    ]

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 end_time : pydantic.types.AwareDatetime
var model_config
var start_time : pydantic.types.AwareDatetime

Inherited members

class Axis (*args, **kwds)
Expand source code
class Axis(StrEnum):
    async_adcp_versions = 'async_adcp_versions'
    webhook_signing_algorithms = 'webhook_signing_algorithms'
    experimental_features = 'experimental_features'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var async_adcp_versions
var experimental_features
var webhook_signing_algorithms
class BadgeRole (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class BadgeRole(RootModel[adcp_protocol.AdcpProtocol]):
    root: adcp_protocol.AdcpProtocol

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[AdcpProtocol]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : AdcpProtocol
class Bank (**data: Any)
Expand source code
class Bank(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    account_holder: Annotated[str, Field(description='Name on the bank account', max_length=200)]
    iban: Annotated[
        str | None,
        Field(
            description='International Bank Account Number (SEPA markets)',
            pattern='^[A-Z]{2}[0-9]{2}[A-Z0-9]{4,30}$',
        ),
    ] = None
    bic: Annotated[
        str | None,
        Field(
            description='Bank Identifier Code / SWIFT code (SEPA markets)',
            pattern='^[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?$',
        ),
    ] = None
    routing_number: Annotated[
        str | None,
        Field(
            description='Bank routing number for non-SEPA markets (e.g., US ABA routing number, Canadian transit/institution number)',
            max_length=30,
        ),
    ] = None
    account_number: Annotated[
        str | None, Field(description='Bank account number for non-SEPA markets', max_length=30)
    ] = 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 account_holder : str
var account_number : str | None
var bic : str | None
var iban : str | None
var model_config
var routing_number : str | None

Inherited members

class BaseGroupAsset (**data: Any)
Expand source code
class BaseGroupAsset(AdCPBaseModel):
    asset_id: Annotated[str, Field(description='Identifier for this asset within the group')]
    asset_role: Annotated[
        str | None,
        Field(
            description="Descriptive label for this asset's purpose. For documentation and UI display only — manifests key assets by asset_id, not asset_role."
        ),
    ] = None
    asset_group_id: Annotated[
        str | None,
        Field(
            description='Optional canonical asset_group_id this slot fills, drawn from /schemas/core/asset-group-vocabulary.json. Same semantics as on baseIndividualAsset — lets buyers and migration tools resolve v1 author-invented slot names to canonical names.'
        ),
    ] = None
    required: Annotated[
        StrictBool,
        Field(description='Whether this asset is required within each repetition of the group'),
    ]
    overlays: Annotated[
        list[overlay.Overlay] | None,
        Field(
            description="Publisher-controlled elements rendered on top of buyer content at this asset's position (e.g., carousel navigation arrows, slide indicators). Creative agents should avoid placing critical content within overlay bounds."
        ),
    ] = 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 asset_group_id : str | None
var asset_id : str
var asset_role : str | None
var model_config
var overlays : list[Overlay] | None
var required : bool

Inherited members

class BaseIndividualAsset (**data: Any)
Expand source code
class BaseIndividualAsset(AdCPBaseModel):
    item_type: Annotated[
        Literal['individual'],
        Field(description='Discriminator indicating this is an individual asset'),
    ] = 'individual'
    asset_id: Annotated[
        str,
        Field(
            description='Unique identifier for this asset. Creative manifests MUST use this exact value as the key in the assets object.'
        ),
    ]
    asset_role: Annotated[
        str | None,
        Field(
            description="Descriptive label for this asset's purpose (e.g., 'hero_image', 'logo', 'third_party_tracking'). For documentation and UI display only — manifests key assets by asset_id, not asset_role."
        ),
    ] = None
    required: Annotated[
        StrictBool,
        Field(
            description='Whether this asset is required (true) or optional (false). Required assets must be provided for a valid creative. Optional assets enhance the creative but are not mandatory.'
        ),
    ]
    overlays: Annotated[
        list[overlay.Overlay] | None,
        Field(
            description="Publisher-controlled elements rendered on top of buyer content at this asset's position (e.g., video player controls, publisher logos). Creative agents should avoid placing critical content (CTAs, logos, key copy) within overlay bounds."
        ),
    ] = None
    asset_group_id: Annotated[
        str | None,
        Field(
            description="Optional canonical asset_group_id this slot fills, drawn from /schemas/core/asset-group-vocabulary.json. Lets buyers and migration tools resolve v1 author-invented slot names (e.g., `click_url`) to canonical names (e.g., `landing_page_url`). Validators MAY soft-warn when a v1 slot's asset_id is a known alias but no asset_group_id is declared."
        ),
    ] = 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 asset_group_id : str | None
var asset_id : str
var asset_role : str | None
var item_type : Literal['individual']
var model_config
var overlays : list[Overlay] | None
var required : bool

Inherited members

class Basis (*args, **kwds)
Expand source code
class Basis(StrEnum):
    reporting_ledger = 'reporting_ledger'
    third_party_attestation = 'third_party_attestation'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var reporting_ledger
var third_party_attestation
class BiddingPolicy (**data: Any)
Expand source code
class BiddingPolicy(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    automatic: Annotated[
        Literal[True] | None,
        Field(
            description='Explicitly use seller/provider automatic bidding at this authored scope. At package scope this is a complete override of a media-buy policy, not inheritance. It MUST be the only field in the block and MUST be preserved on readback.'
        ),
    ] = None
    bid_amount: Annotated[
        StrictFloat | None,
        Field(
            description="Manual auction bid denominated in the media-buy currency and expressed per the selected pricing option's auction unit. For example, a CPM option interprets the amount per thousand impressions. This is the amount submitted to the auction, not a promise that the clearing price equals it. Requires an auction-priced pricing option whose currency equals the media-buy currency.",
            gt=0.0,
        ),
    ] = None
    max_bid: Annotated[
        StrictFloat | None,
        Field(
            description="Hard per-auction ceiling denominated in the media-buy currency and expressed per the selected pricing option's auction unit. This is the only canonical hard auction ceiling and MUST NOT be translated into an average outcome-cost control. Requires an auction-priced pricing option whose currency equals the media-buy currency. May stand alone or supplement cost_per/roas only when the relevant scope capability advertises that combination.",
            gt=0.0,
        ),
    ] = None
    cost_per: Annotated[
        CostPer | None,
        Field(
            description="Average cost control per result of the scope-bound primary optimization goal. At seller-optimized media-buy scope it binds to budget_allocation.optimization_goals; at package scope it binds to that package's optimization_goals; at fixed media-buy scope it binds independently to each inheriting package and is valid only when their primary-goal result units are compatible. Metric goals are compatible only when metric and every result-defining qualifier match; vendor_metric goals only when vendor and metric_id match; event goals only when the event_type/custom_event_name set and resolved attribution_window match. Primary is the earliest array entry among goals tied for the lowest explicit numeric priority; unprioritized goals follow explicitly prioritized goals; when all priorities are absent, the first entry is primary."
        ),
    ] = None
    roas: Annotated[
        Roas | None,
        Field(
            description='Dimensionless return-on-ad-spend control bound to the same scope-specific primary goal rules as cost_per. The bound goal must be value-bearing; a fixed media-buy default requires a value-bearing primary goal on every inheriting package. Every referenced value-bearing event source MUST declare value_currencies containing the media-buy currency. The seller validates this at buy creation; each buy consumes only exact-currency records, while other declared currencies remain available to other buys. Sellers MUST NOT perform currency conversion.'
        ),
    ] = 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 automatic : Literal[True] | None
var bid_amount : float | None
var cost_per : CostPer | None
var max_bid : float | None
var model_config
var roas : Roas | None

Inherited members

class BiddingPolicyCapability (**data: Any)
Expand source code
class BiddingPolicyCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    media_buy: Annotated[
        ScopeCapability | None,
        Field(
            description='Policies accepted at media-buy scope and inherited by packages that omit a package override.'
        ),
    ] = None
    package: Annotated[
        ScopeCapability | None,
        Field(
            description='Policies accepted as package-authored policies, including explicit automatic overrides.'
        ),
    ] = 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 media_buy : ScopeCapability | None
var model_config
var package : ScopeCapability | None

Inherited members

class BitDepth (*args, **kwds)
Expand source code
class BitDepth(IntEnum):
    integer_16 = 16
    integer_24 = 24
    integer_32 = 32

Enum where members are also (and must be) ints

Ancestors

  • enum.IntEnum
  • builtins.int
  • enum.ReprEnum
  • enum.Enum

Class variables

var integer_16
var integer_24
var integer_32
class Bleed (**data: Any)
Expand source code
class Bleed(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    uniform: Annotated[StrictFloat, Field(description='Same bleed on all four sides', ge=0.0)]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var uniform : float

Inherited members

class Bleed1 (**data: Any)
Expand source code
class Bleed1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    top: Annotated[StrictFloat, Field(ge=0.0)]
    right: Annotated[StrictFloat, Field(ge=0.0)]
    bottom: Annotated[StrictFloat, Field(ge=0.0)]
    left: Annotated[StrictFloat, Field(ge=0.0)]

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 bottom : float
var left : float
var model_config
var right : float
var top : float

Inherited members

class BlockedImpacts (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class BlockedImpacts(RootModel[list[Impact]]):
    root: Annotated[
        list[Impact],
        Field(
            description='Account areas evaluated for a blocked change. At least one impact identifies the blocking area.',
            max_length=16,
            min_length=1,
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[list[Impact]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[Impact]
class Blocker (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class Blocker(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 1000, 'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class BodyStyle (*args, **kwds)
Expand source code
class BodyStyle(StrEnum):
    sedan = 'sedan'
    suv = 'suv'
    truck = 'truck'
    coupe = 'coupe'
    convertible = 'convertible'
    wagon = 'wagon'
    van = 'van'
    hatchback = 'hatchback'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var convertible
var coupe
var hatchback
var sedan
var suv
var truck
var van
var wagon
class Bounds (**data: Any)
Expand source code
class Bounds(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    x: Annotated[StrictFloat, Field(description="Horizontal offset from the asset's left edge")]
    y: Annotated[StrictFloat, Field(description="Vertical offset from the asset's top edge")]
    width: Annotated[StrictFloat, Field(description='Width of the overlay', ge=0.0)]
    height: Annotated[StrictFloat, Field(description='Height of the overlay', ge=0.0)]
    unit: Annotated[
        Unit,
        Field(
            description="'px' = absolute pixels from asset top-left. 'fraction' = proportional to asset dimensions (0.0 = edge, 1.0 = opposite edge). 'inches', 'cm', 'mm', 'pt' (1/72 inch) = physical units for print overlays, measured from asset top-left."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var height : float
var model_config
var unit : Unit
var width : float
var x : float
var y : float

Inherited members

class BoxDecoration (**data: Any)
Expand source code
class BoxDecoration(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['box'] = 'box'
    layer: Layer
    bounds: Rectangle
    fill_color: Color

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 bounds : Rectangle
var fill_color : Color
var kind : Literal['box']
var layer : Layer
var model_config

Inherited members

class BrandAgent (**data: Any)
Expand source code
class BrandAgent(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    url: Annotated[AnyUrl, Field(description='MCP endpoint URL of the brand agent.')]
    id: Annotated[str, Field(description='Agent identifier.')]

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 id : str
var model_config
var url : pydantic.networks.AnyUrl

Inherited members

class BrandId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class BrandId(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-z0-9_]+$'}
    _json_schema_extra = {
        'description': 'Identifier for a brand within a house portfolio. Must be lowercase alphanumeric with underscores only. The house chooses this identifier.',
        'examples': ['tide', 'cheerios', 'air_jordan', 'nike', 'pampers'],
        'title': 'Brand ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class BrandKey (**data: Any)
Expand source code
class BrandKey(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    domain: Annotated[
        str,
        Field(
            description='Domain that hosts /.well-known/brand.json or is registered for the brand.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    brand_id: Annotated[
        brand_id_1.BrandId | None,
        Field(
            description='Brand within a house-of-brands manifest. Omit for a single-brand domain.'
        ),
    ] = None
    countries: Annotated[
        list[Country] | None,
        Field(
            description='Canonical set of ISO 3166-1 alpha-2 countries for this advertiser identity. Omit when the identity is global or the house does not split the brand geographically. Array order is not meaningful; producers MUST sort codes lexicographically before computing keys or signatures. This qualifies account and proposal identity and is not delivery targeting.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var brand_id : BrandId | None
var countries : list[Country] | None
var domain : str
var model_config

Inherited members

class BrandKitOverride (**data: Any)
Expand source code
class BrandKitOverride(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    logo: Annotated[image_asset.ImageAsset | None, Field(description='Override logo asset.')] = None
    colors: Annotated[Colors | None, Field(description='Override brand colors (hex strings).')] = (
        None
    )
    voice: Annotated[
        str | None,
        Field(
            description='Override brand-voice description for surface-composed text/audio output.'
        ),
    ] = None
    tagline: Annotated[str | None, Field(description='Override tagline.')] = 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 colors : Colors | None
var model_config
var tagline : str | None
var voice : str | None

Inherited members

class BrandReference (**data: Any)
Expand source code
class BrandReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    domain: Annotated[
        str,
        Field(
            description="Domain where /.well-known/brand.json is hosted, or the brand's operating domain",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    brand_id: Annotated[
        brand_id_1.BrandId | None,
        Field(
            description='Brand identifier within the house portfolio. Optional for single-brand domains.'
        ),
    ] = None
    countries: Annotated[
        list[Country] | None,
        Field(
            description='Canonical set of ISO 3166-1 alpha-2 countries for this advertiser identity. Omit for a global/default identity. Array order is not meaningful; producers MUST sort codes lexicographically before computing keys or signatures. This qualifies account identity and is not delivery targeting.',
            min_length=1,
        ),
    ] = None
    industries: Annotated[
        list[str] | None,
        Field(
            description="Inline override for the brand's industries. Useful when the caller cannot modify the brand's canonical brand.json but needs to declare industries for governance (e.g., Annex III vertical detection). brand.json remains the canonical source; when omitted here, governance agents SHOULD resolve from brand.json."
        ),
    ] = None
    data_subject_contestation: Annotated[
        DataSubjectContestation | None,
        Field(
            description="Inline override for the brand's contestation contact point. Useful when the operator does not control brand.json but needs to discharge Art 22(3) for this plan. brand.json is canonical; when omitted, governance agents resolve brand → house → missing."
        ),
    ] = None
    brand_kit_override: Annotated[
        BrandKitOverride | None,
        Field(
            description="Inline override for brand-kit fields normally resolved from `/.well-known/brand.json` on `domain` (logo, colors, voice, tagline). Use when brand.json is missing, stale, or inappropriate for this specific call — e.g., a campaign-scoped tagline, a co-branded creative, a freshly-rebranded color palette the brand.json hasn't shipped yet. Same inline-override pattern as `industries` and `data_subject_contestation` above: brand.json is canonical, the override is per-call. Adopters needing to override fields outside this subset (`voice_attributes`, `prohibited_terms`, etc.) MUST publish a different brand.json and reference it via a different `domain` — the inline override is intentionally narrow to a small high-traffic subset.\n\n**Merge semantics (normative).** The merge is **field-level**, not whole-object replacement. Each field within `brand_kit_override` (`logo`, `colors`, `voice`, `tagline`) is evaluated independently — when a field is present on the override the override value applies; when a field is absent the brand.json value applies (or is absent if brand.json doesn't carry one either). For composite fields (`colors.primary`, `colors.secondary`, `colors.accent`), the merge is one level deeper: each color slot is evaluated independently — a producer can override `colors.primary` while still inheriting `colors.secondary` from brand.json. SDKs MUST NOT treat a present `brand_kit_override.colors` as wiping the brand.json `colors` block entirely; only the per-slot fields present in the override take precedence. Without this rule, a partial-override semantics would diverge across SDKs and produce inconsistent rendering for the same payload."
        ),
    ] = 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 brand_id : BrandId | None
var brand_kit_override : BrandKitOverride | None
var countries : list[Country] | None
var data_subject_contestation : DataSubjectContestation | None
var domain : str
var industries : list[str] | None
var model_config

Inherited members

class BrandResponseAuthorizationResult1 (**data: Any)
Expand source code
class BrandResponseAuthorizationResult1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    trust: Annotated[
        Literal['trusted'],
        Field(
            description='Whether the signing key was bound to the asserted brand_domain through an authorized brand-agent entry. An untrusted result MUST NOT extend or revoke relationship trust on its own.'
        ),
    ] = 'trusted'
    reason: Annotated[
        Reason | None, Field(description='Machine-readable reason for an untrusted result.')
    ] = None
    kid: Annotated[str, Field(description='JWS kid evaluated by the cross-check.', min_length=1)]
    jwks_uri: Annotated[
        AnyUrl,
        Field(
            description='JWKS URI selected only from the matched brand.json agent entry, or its same-origin default.'
        ),
    ]

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 jwks_uri : pydantic.networks.AnyUrl
var kid : str
var model_config
var reason : Reason | None
var trust : Literal['trusted']

Inherited members

class BrandResponseAuthorizationResult2 (**data: Any)
Expand source code
class BrandResponseAuthorizationResult2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    trust: Annotated[
        Literal['untrusted'],
        Field(
            description='Whether the signing key was bound to the asserted brand_domain through an authorized brand-agent entry. An untrusted result MUST NOT extend or revoke relationship trust on its own.'
        ),
    ] = 'untrusted'
    reason: Annotated[Reason, Field(description='Machine-readable reason for an untrusted result.')]
    kid: Annotated[
        str | None, Field(description='JWS kid evaluated by the cross-check.', min_length=1)
    ] = None
    jwks_uri: Annotated[
        AnyUrl | None,
        Field(
            description='JWKS URI selected only from the matched brand.json agent entry, or its same-origin default.'
        ),
    ] = 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 jwks_uri : pydantic.networks.AnyUrl | None
var kid : str | None
var model_config
var reason : Reason
var trust : Literal['untrusted']

Inherited members

class BrowserRequirement (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class BrowserRequirement(RootModel[Required | BrowserRequirement1]):
    root: Required | BrowserRequirement1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Union[Required, BrowserRequirement1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Required | BrowserRequirement1
class BrowserRequirement1 (**data: Any)
Expand source code
class BrowserRequirement1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    families: Annotated[list[browser_family.BrowserFamily], Field(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 families : list[BrowserFamily]
var model_config

Inherited members

class BrowserSupport (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class BrowserSupport(RootModel[Supported | BrowserSupport1]):
    root: Supported | BrowserSupport1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Union[Supported, BrowserSupport1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Supported | BrowserSupport1
class BrowserSupport1 (**data: Any)
Expand source code
class BrowserSupport1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    families: Annotated[list[browser_family.BrowserFamily], Field(min_length=1)]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var families : list[BrowserFamily]
var model_config

Inherited members

class BucketCompleteness (*args, **kwds)
Expand source code
class BucketCompleteness(StrEnum):
    complete = 'complete'
    partial = 'partial'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var complete
var partial
class BucketSemantics (*args, **kwds)
Expand source code
class BucketSemantics(StrEnum):
    exclusive = 'exclusive'
    overlapping = 'overlapping'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var exclusive
var overlapping
class BudgetAllocation1 (**data: Any)
Expand source code
class BudgetAllocation1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Annotated[
        Literal['fixed'],
        Field(
            description='Packages have independent budgets. The seller does not automatically move budget between packages.'
        ),
    ] = 'fixed'

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 mode : Literal['fixed']
var model_config

Inherited members

class BudgetAllocation2 (**data: Any)
Expand source code
class BudgetAllocation2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Annotated[
        Literal['seller_optimized'],
        Field(
            description='Packages draw from a shared media-buy budget. The seller continuously allocates spend across packages to optimize the declared goals.'
        ),
    ] = 'seller_optimized'
    optimization_goals: Annotated[
        list[OptimizationGoal],
        Field(
            description='Goals the seller uses to allocate the shared budget across packages. These are distinct from packages[].optimization_goals, which optimize delivery within an individual package. The primary goal is the earliest array entry among goals with the lowest explicit numeric priority; goals without priority follow all explicitly prioritized goals; when all priorities are omitted, the first entry is primary. It supplies the result unit/value source for media-buy bidding.cost_per or bidding.roas. Legacy monetary target kinds are prohibited at allocation scope because canonical controls belong in media-buy bidding. Every participating product MUST support the primary cross-package goal; otherwise the seller MUST reject the request with TERMS_REJECTED or UNSUPPORTED_FEATURE and identify the incompatible package.',
            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 mode : Literal['seller_optimized']
var model_config
var optimization_goals : list[OptimizationGoal5 | OptimizationGoal6 | OptimizationGoal7]

Inherited members

class BuildCreativeInputRequired (**data: Any)
Expand source code
class BuildCreativeInputRequired(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    reason: Annotated[
        Reason | None, Field(description='Reason code indicating why input is needed')
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional validation errors or warnings explaining why input is required.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var model_config
var reason : Reason | None

Inherited members

class BuildCreativeSubmitted (**data: Any)
Expand source code
class BuildCreativeSubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal. Discriminates this async envelope from the synchronous success shapes, whose creative_manifest or creative_manifests are issued in-line. See task-status.json for the full task-status enum.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='Task handle the buyer uses with get_task_status (or the legacy AdCP tasks/get alias), and that the seller references on push-notification callbacks. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A Task id.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description="Optional human-readable explanation of why the task is submitted — e.g., 'Generative build queued; typical turnaround 3–5 minutes.' Plain text only. Buyers MUST treat this as untrusted seller input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile seller may inject prompt-injection payloads aimed at the buyer's agent.",
            max_length=2000,
        ),
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories, governance observations). Terminal failures belong in the error branch, not here.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class BuildCreativeWorking (**data: Any)
Expand source code
class BuildCreativeWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0)
    ] = None
    current_step: Annotated[
        str | None,
        Field(
            description="Current step or phase of the operation (e.g., 'generating_assets', 'resolving_macros', 'rendering_preview')"
        ),
    ] = None
    total_steps: Annotated[
        SchemaInt | None, Field(description='Total number of steps in the operation', ge=1)
    ] = None
    step_number: Annotated[SchemaInt | None, Field(description='Current step number', ge=1)] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var current_step : str | None
var ext : ExtensionObject | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class BusinessEntity (**data: Any)
Expand source code
class BusinessEntity(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    legal_name: Annotated[
        str, Field(description='Registered legal name of the business entity', max_length=200)
    ]
    vat_id: Annotated[
        str | None,
        Field(
            description='VAT identification number (e.g., DE123456789 for Germany, FR12345678901 for France). Required for B2B invoicing in the EU. Must be normalized: no spaces, dots, or dashes.',
            pattern='^[A-Z]{2}[A-Z0-9]{2,13}$',
        ),
    ] = None
    tax_id: Annotated[
        str | None,
        Field(
            description='Tax identification number for jurisdictions that do not use VAT (e.g., US EIN)',
            max_length=30,
        ),
    ] = None
    registration_number: Annotated[
        str | None,
        Field(
            description='Company registration number (e.g., HRB 12345 for German Handelsregister)',
            max_length=50,
        ),
    ] = None
    address: Annotated[
        Address | None, Field(description='Postal address for invoicing and legal correspondence')
    ] = None
    contacts: Annotated[
        list[Contact] | None,
        Field(
            description='Contacts for billing, legal, and operational matters. Contains personal data subject to GDPR and equivalent regulations. Implementations MUST use this data only for invoicing and account management.',
            max_length=10,
        ),
    ] = None
    bank: Annotated[
        Bank | None,
        Field(
            description='Bank account details for payment processing. Write-only: included in requests to provide payment coordinates, but MUST NOT be echoed in responses. Sellers store these details and confirm receipt without returning them.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var address : Address | None
var bank : Bank | None
var contacts : list[Contact] | None
var ext : ExtensionObject | None
var legal_name : str
var model_config
var registration_number : str | None
var tax_id : str | None
var vat_id : str | None

Inherited members

class BuyProductsInputRequired (**data: Any)
Expand source code
class BuyProductsInputRequired(CompactTaskInputRequired):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class BuyProductsSubmitted (**data: Any)
Expand source code
class BuyProductsSubmitted(CompactTaskSubmitted):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class BuyProductsWorking (**data: Any)
Expand source code
class BuyProductsWorking(CompactTaskWorking):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class BuyerReason (**data: Any)
Expand source code
class BuyerReason(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    code: Annotated[
        str,
        Field(
            description="Machine-readable buyer-actionable reason from the standard `enums/error-code.json` vocabulary or a producer-specific extension. Extensions MUST follow the standard `X_{VENDOR}_{CODE}` naming rule. The wire field is open for forward compatibility. Receivers MUST accept unknown values and use the enclosing `error.recovery` plus this object's `message` as the fallback.",
            max_length=64,
            min_length=1,
        ),
    ]
    message: Annotated[
        str,
        Field(
            description='Buyer-safe explanation of the actionable failure. MUST NOT expose vendor identifiers, ad-server type names, internal object names, internal IDs, stack traces, or other producer-private implementation details.',
            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 code : str
var message : str
var model_config

Inherited members

class ByActionSourceItem (**data: Any)
Expand source code
class ByActionSourceItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    action_source: Annotated[
        action_source_1.ActionSource, Field(description='Where the conversion occurred')
    ]
    event_source_id: Annotated[
        str | None,
        Field(
            description='Event source that produced these conversions (for disambiguation when multiple event sources are configured)'
        ),
    ] = None
    count: Annotated[
        StrictFloat, Field(description='Number of conversions from this action source', ge=0.0)
    ]
    value: Annotated[
        StrictFloat | None,
        Field(description='Total monetary value of conversions from this action source', ge=0.0),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var action_source : ActionSource
var count : float
var event_source_id : str | None
var model_config
var value : float | None

Inherited members

class ByEventTypeItem (**data: Any)
Expand source code
class ByEventTypeItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    event_type: Annotated[event_type_1.EventType, Field(description='The event type')]
    event_source_id: Annotated[
        str | None,
        Field(
            description='Event source that produced these conversions (for disambiguation when multiple event sources are configured)'
        ),
    ] = None
    count: Annotated[StrictFloat, Field(description='Number of events of this type', ge=0.0)]
    value: Annotated[
        StrictFloat | None, Field(description='Total monetary value of events of this type', ge=0.0)
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var count : float
var event_source_id : str | None
var event_type : EventType
var model_config
var value : float | None

Inherited members

class C2paWatermarkAction (*args, **kwds)
Expand source code
class C2paWatermarkAction(StrEnum):
    c2pa_watermarked_bound = 'c2pa.watermarked.bound'
    c2pa_watermarked_unbound = 'c2pa.watermarked.unbound'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var c2pa_watermarked_bound
var c2pa_watermarked_unbound
class CAEnum (*args, **kwds)
Expand source code
class CAEnum(StrEnum):
    fsa = 'fsa'
    full = 'full'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var fsa
var full
class CacheScope (*args, **kwds)
Expand source code
class CacheScope(StrEnum):
    public = 'public'
    account = 'account'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var account
var public
class Calendar (**data: Any)
Expand source code
class Calendar(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    timezone_basis: ReportCalendarTimezoneBasis
    timezone: Annotated[str | None, Field(max_length=255, min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var timezone : str | None
var timezone_basis : ReportCalendarTimezoneBasis

Inherited members

class CancellationFee (**data: Any)
Expand source code
class CancellationFee(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Type,
        Field(
            description="Fee calculation method. 'percent_remaining': percentage of remaining uncommitted spend. 'full_commitment': buyer owes the full committed budget regardless of delivery. 'fixed_fee': flat monetary amount. 'none': no financial fee (cancellation with notice is free)."
        ),
    ]
    rate: Annotated[
        StrictFloat | None,
        Field(
            description="Fee rate as a decimal proportion of remaining committed spend. Required when type is 'percent_remaining' (e.g., 0.5 means 50% of remaining spend).",
            ge=0.0,
            le=1.0,
        ),
    ] = None
    amount: Annotated[
        StrictFloat | None,
        Field(
            description="Fixed fee amount in the buy's currency. Required when type is 'fixed_fee'.",
            ge=0.0,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var amount : float | None
var model_config
var rate : float | None
var type : Type

Inherited members

class CancellationPolicy (**data: Any)
Expand source code
class CancellationPolicy(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    notice_period: Annotated[
        duration.Duration,
        Field(
            description="Minimum notice period before cancellation takes effect (e.g., { interval: 30, unit: 'days' }). A guaranteed buy canceled without sufficient notice incurs the declared cancellation fee."
        ),
    ]
    cancellation_fee: Annotated[
        CancellationFee, Field(description='Fee applied when the notice period is not met.')
    ]

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 cancellation_fee : CancellationFee
var model_config
var notice_period : Duration

Inherited members

class CanonicalAccountReference1 (**data: Any)
Expand source code
class CanonicalAccountReference1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    account_id: Annotated[str, Field(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 account_id : str
var model_config

Inherited members

class CanonicalAccountReference2 (**data: Any)
Expand source code
class CanonicalAccountReference2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    brand: brand_key.BrandKey
    operator: Annotated[
        str, Field(pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$')
    ]
    operator_unit: Annotated[
        operator_unit_1.OperatorUnit | None,
        Field(
            description='Optional operator-owned business unit, agency seat, or platform account. Only id participates in identity; name is mutable display metadata.'
        ),
    ] = None
    currency: Annotated[
        str | None,
        Field(
            description='Immutable ISO 4217 transaction currency when the advertiser object is currency-bound. When present, this is part of the natural key and all media buys on the account use it. Omit for per-media-buy currency selection.',
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    timezone: Annotated[
        str | None,
        Field(
            description='Immutable account timezone. Include it in the natural key only for buyer-selected account_fixed provisioning.',
            min_length=1,
        ),
    ] = None
    sandbox: StrictBool | None = 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 brand : BrandKey
var currency : str | None
var model_config
var operator : str
var operator_unit : OperatorUnit | None
var sandbox : bool | None
var timezone : str | None

Inherited members

class CanonicalAudienceEvidence (**data: Any)
Expand source code
class CanonicalAudienceEvidence(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    evidence_id: Annotated[str, Field(min_length=1)]
    snapshot_id: Annotated[str, Field(min_length=1)]
    version: Annotated[str, Field(min_length=1)]
    content_digest: Annotated[str, Field(pattern='^sha256:[a-f0-9]{64}$')]
    audience: audience_characteristic.AudienceCharacteristic
    relationship: Relationship
    value: Annotated[StrictFloat, Field(ge=0.0)]
    unit: Unit
    baseline: Baseline
    evidence_type: EvidenceType
    methodology: audience_evidence_methodology.AudienceEvidenceMethodology
    subject_type: audience_subject_type.AudienceSubjectType
    resolution_method: audience_resolution_method.AudienceResolutionMethod | None = None
    provider: brand_key.BrandKey
    measurement_window: date_range.DateRange
    sample_size: Annotated[SchemaInt | None, Field(ge=1)] = None
    confidence: Annotated[StrictFloat | None, Field(ge=0.0, le=1.0)] = None
    last_updated: AwareDatetime
    methodology_url: AnyUrl | None = None
    attestation_digests: Annotated[
        list[AttestationDigest] | None,
        Field(
            description='Portable-attestation reference digests available through the evidence provider; credential bodies are not inlined into product discovery.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 attestation_digests : list[AttestationDigest] | None
var audience : AudienceCharacteristic
var baseline : Baseline
var confidence : float | None
var content_digest : str
var evidence_id : str
var evidence_type : EvidenceType
var ext : ExtensionObject | None
var last_updated : pydantic.types.AwareDatetime
var measurement_window : DateRange
var methodology : AudienceEvidenceMethodology
var methodology_url : pydantic.networks.AnyUrl | None
var model_config
var provider : BrandKey
var relationship : Relationship
var resolution_method : AudienceResolutionMethod | None
var sample_size : int | None
var snapshot_id : str
var subject_type : AudienceSubjectType
var unit : Unit
var value : float
var version : str

Inherited members

class CanonicalAudienceEvidenceSelection (**data: Any)
Expand source code
class CanonicalAudienceEvidenceSelection(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    evidence_id: Annotated[str, Field(min_length=1)]
    snapshot_id: Annotated[str, Field(min_length=1)]
    version: Annotated[str, Field(min_length=1)]
    content_digest: Annotated[str, Field(pattern='^sha256:[a-f0-9]{64}$')]
    decision_use: DecisionUse
    evidence: canonical_audience_evidence.CanonicalAudienceEvidence | None = None
    verified_attestation_digests: Annotated[
        list[VerifiedAttestationDigest] | None, Field(min_length=1)
    ] = None
    ext: ext_1.ExtensionObject | 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 content_digest : str
var decision_use : DecisionUse
var evidence : CanonicalAudienceEvidence | None
var evidence_id : str
var ext : ExtensionObject | None
var model_config
var snapshot_id : str
var verified_attestation_digests : list[VerifiedAttestationDigest] | None
var version : str

Inherited members

class CanonicalBudgetAllocation1 (**data: Any)
Expand source code
class CanonicalBudgetAllocation1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['fixed'] = 'fixed'

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 mode : Literal['fixed']
var model_config

Inherited members

class CanonicalBudgetAllocation2 (**data: Any)
Expand source code
class CanonicalBudgetAllocation2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['seller_optimized'] = 'seller_optimized'
    optimization_goals: Annotated[
        list[canonical_optimization_goal.CanonicalOptimizationGoal], Field(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 mode : Literal['seller_optimized']
var model_config
var optimization_goals : list[CanonicalOptimizationGoal1 | CanonicalOptimizationGoal2 | CanonicalOptimizationGoal3]

Inherited members

class CanonicalDeliveryForecast (**data: Any)
Expand source code
class CanonicalDeliveryForecast(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    points: Annotated[list[canonical_forecast_point.CanonicalForecastPoint], Field(min_length=1)]
    forecast_range_unit: forecast_range_unit_1.ForecastRangeUnit | None = None
    method: forecast_method.ForecastMethod
    currency: Annotated[str, Field(pattern='^[A-Z]{3}$')]
    demographic_system: demographic_system_1.DemographicSystem | None = None
    demographic: str | None = None
    measurement_source: Annotated[str | None, Field(max_length=64, pattern='^[a-z0-9_]+$')] = None
    reach_unit: reach_unit_1.ReachUnit | None = None
    generated_at: AwareDatetime | None = None
    valid_until: AwareDatetime | None = None
    ext: ext_1.ExtensionObject | 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 currency : str
var demographic : str | None
var demographic_system : DemographicSystem | None
var ext : ExtensionObject | None
var forecast_range_unit : ForecastRangeUnit | None
var generated_at : pydantic.types.AwareDatetime | None
var measurement_source : str | None
var method : ForecastMethod
var model_config
var points : list[CanonicalForecastPoint]
var reach_unit : ReachUnit | None
var valid_until : pydantic.types.AwareDatetime | None

Inherited members

class CanonicalDoohPlacementAttributes (**data: Any)
Expand source code
class CanonicalDoohPlacementAttributes(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    slot_duration_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Scheduled duration of one ad slot in seconds; not the creative-duration contract.',
            ge=1,
        ),
    ] = None
    loop_duration_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Duration of the full ad loop rotation in seconds and the canonical source for loop duration.',
            ge=1,
        ),
    ] = None
    screen_resolution: CanonicalDoohScreenResolution | None = None
    motion: Annotated[
        dooh_motion_type.DoohMotionType | None,
        Field(
            description='Physical motion capability of a visual DOOH screen, not an accepted-format declaration. Omit for audio-only placements.'
        ),
    ] = 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 loop_duration_seconds : int | None
var model_config
var motion : DoohMotionType | None
var screen_resolution : CanonicalDoohScreenResolution | None
var slot_duration_seconds : int | None

Inherited members

class CanonicalDoohScreenResolution (**data: Any)
Expand source code
class CanonicalDoohScreenResolution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    width: Annotated[SchemaInt, Field(ge=1)]
    height: Annotated[SchemaInt, Field(ge=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 height : int
var model_config
var width : int

Inherited members

class CanonicalForecastPoint (**data: Any)
Expand source code
class CanonicalForecastPoint(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    label: Annotated[str | None, Field(max_length=128)] = None
    budget: Annotated[StrictFloat | None, Field(ge=0.0)] = None
    product_id: str | None = None
    dimensions: forecast_point_dimensions.ForecastPointDimensions | None = None
    availability_status: availability_status_1.AvailabilityStatus | None = None
    metrics: Metrics
    viewability: Viewability | None = None
    vendor_metric_values: (
        list[canonical_forecast_vendor_metric_value.CanonicalForecastVendorMetricValue] | 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 availability_status : AvailabilityStatus | None
var budget : float | None
var dimensions : ForecastPointDimensions | None
var label : str | None
var metrics : Metrics
var model_config
var product_id : str | None
var vendor_metric_values : list[CanonicalForecastVendorMetricValue] | None
var viewability : Viewability | None

Inherited members

class CanonicalForecastVendorMetricValue (**data: Any)
Expand source code
class CanonicalForecastVendorMetricValue(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    vendor: brand_key.BrandKey
    metric_id: vendor_metric_id.VendorMetricId
    value: forecast_range.ForecastRange
    unit: str | None = None
    measurable_impressions: forecast_range.ForecastRange | None = None
    breakdown: 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 breakdown : dict[str, typing.Any] | None
var measurable_impressions : ForecastRange | None
var metric_id : VendorMetricId
var model_config
var unit : str | None
var value : ForecastRange
var vendor : BrandKey

Inherited members

class CanonicalFormatKind (*args, **kwds)
Expand source code
class CanonicalFormatKind(StrEnum):
    image = 'image'
    html5 = 'html5'
    display_tag = 'display_tag'
    image_carousel = 'image_carousel'
    video_hosted = 'video_hosted'
    video_vast = 'video_vast'
    audio_hosted = 'audio_hosted'
    audio_vast = 'audio_vast'
    audio_daast = 'audio_daast'
    sponsored_placement = 'sponsored_placement'
    native_in_feed = 'native_in_feed'
    responsive_creative = 'responsive_creative'
    agent_placement = 'agent_placement'
    seller_rendered_stateful_display = 'seller_rendered_stateful_display'
    coordinated_placements = 'coordinated_placements'
    custom = 'custom'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var agent_placement
var audio_daast
var audio_hosted
var audio_vast
var coordinated_placements
var custom
var display_tag
var html5
var image
var native_in_feed
var responsive_creative
var seller_rendered_stateful_display
var sponsored_placement
var video_hosted
var video_vast
class CanonicalFormatOption (**data: Any)
Expand source code
class CanonicalFormatOption(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    format_option_id: Annotated[str | None, Field(min_length=1)] = None
    publisher_domain: Annotated[
        str | None,
        Field(pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$'),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored production commitment for first-class manifest tracker execution. Presence requires a stable format_option_id. Creative-agent projections MUST strip this authority-bearing field.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='When true, every technical creative-acceptance constraint for this declaration layer is expressed and omitted technical fields mean no constraint. When false or absent, omitted technical fields are undeclared and MUST NOT be inferred. The effective contract is complete only when every applicable declaration layer asserts true.'
        ),
    ] = None
    display_name: Annotated[str | None, Field(min_length=1)] = None
    sample_render_url: AnyUrl | None = None
    applies_to_channels: Annotated[list[channels.MediaChannel] | None, Field(min_length=1)] = None
    seller_preference: SellerPreference | None = None
    locale_policy: creative_locale_policy.CreativeLocalePolicy | None = None
    canonical_formats_only: StrictBool | None = False
    experimental: StrictBool | None = False
    format_kind: FormatKind
    params: dict[str, Any]
    format_shape: Annotated[str | None, Field(min_length=1)] = None
    format_schema: platform_extension_ref.PlatformExtensionReference | 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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : FormatKind
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : dict[str, typing.Any]
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None

Inherited members

class CanonicalMeasurementTerms (**data: Any)
Expand source code
class CanonicalMeasurementTerms(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    billing_measurement: BillingMeasurement | None = None
    makegood_policy: MakegoodPolicy | 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 billing_measurement : BillingMeasurement | None
var makegood_policy : MakegoodPolicy | None
var model_config

Inherited members

class CanonicalMediaBuyAction1 (**data: Any)
Expand source code
class CanonicalMediaBuyAction1(CanonicalMediaBuyActionFields):
    task: Literal['control_media_buy'] = 'control_media_buy'
    action: Action

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 action : Action
var model_config
var task : Literal['control_media_buy']

Inherited members

class CanonicalMediaBuyAction2 (**data: Any)
Expand source code
class CanonicalMediaBuyAction2(CanonicalMediaBuyActionFields):
    task: Literal['refine_proposals'] = 'refine_proposals'
    action: Action3

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 action : Action3
var model_config
var task : Literal['refine_proposals']

Inherited members

class CanonicalMediaBuyAction3 (**data: Any)
Expand source code
class CanonicalMediaBuyAction3(CanonicalMediaBuyActionFields):
    task: Literal['sync_creatives'] = 'sync_creatives'
    action: Action4 | 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 action : Action4 | None
var model_config
var task : Literal['sync_creatives']

Inherited members

class CanonicalMediaBuyActionFields (**data: Any)
Expand source code
class CanonicalMediaBuyActionFields(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    task: Task
    action: str
    mode: canonical_media_buy_action_mode.CanonicalMediaBuyActionMode
    sla: sla_window.SlaWindow | None = None
    change_term_id: media_buy_change_term_id.MediaBuyChangeTermId | None = None
    terms_ref: media_buy_legacy_terms_ref.MediaBuyTermsReference | None = None
    applicable_package_ids: Annotated[
        list[applicable_package_id.ApplicablePackageId] | None,
        Field(
            description='Exact eligible packages for a package-scoped action; omission means all relevant packages.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Subclasses

Class variables

var action : str
var applicable_package_ids : list[ApplicablePackageId] | None
var change_term_id : MediaBuyChangeTermId | None
var mode : CanonicalMediaBuyActionMode
var model_config
var sla : SlaWindow | None
var task : Task
var terms_ref : MediaBuyTermsReference | None

Inherited members

class CanonicalMediaBuyFeatures (**data: Any)
Expand source code
class CanonicalMediaBuyFeatures(AdCPBaseModel):
    __pydantic_extra__: Dict[str, StrictBool]
    model_config = ConfigDict(
        extra='allow',
    )
    property_filtering: StrictBool | None = None
    catalog_management: StrictBool | None = None
    reporting_commitment_snapshots: Annotated[
        StrictBool | None,
        Field(
            description='Seller preserves the accepted per-purchase reporting contract and exposes it on proposal and MediaBuy readback.'
        ),
    ] = None
    seller_optimized_budget: Annotated[
        StrictBool | None,
        Field(
            description='Core seller-optimized shared-budget contract: shared total_budget, seller allocation across packages, media-buy pacing, and allocation echo.'
        ),
    ] = None
    seller_optimized_package_budgets: Annotated[
        StrictBool | None,
        Field(
            description='Package budget caps inside seller-optimized buys; implies seller_optimized_budget.'
        ),
    ] = None
    seller_optimized_min_spend_targets: Annotated[
        StrictBool | None,
        Field(
            description='Package minimum-spend targets inside seller-optimized buys; implies seller_optimized_budget.'
        ),
    ] = None
    seller_optimized_package_pacing: Annotated[
        StrictBool | None,
        Field(
            description='Package pacing inside seller-optimized buys; implies seller_optimized_budget.'
        ),
    ] = None
    bidding_policy: bidding_policy_capability.BiddingPolicyCapability | 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 bidding_policy : BiddingPolicyCapability | None
var catalog_management : bool | None
var model_config
var property_filtering : bool | None
var reporting_commitment_snapshots : bool | None
var seller_optimized_budget : bool | None
var seller_optimized_min_spend_targets : bool | None
var seller_optimized_package_budgets : bool | None
var seller_optimized_package_pacing : bool | None

Inherited members

class CanonicalMetricQualifier (**data: Any)
Expand source code
class CanonicalMetricQualifier(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    viewability_standard: viewability_standard_1.ViewabilityStandard | None = None
    completion_source: completion_source_1.CompletionSource | None = None
    attribution_methodology: attribution_methodology_1.AttributionMethodology | None = None
    attribution_window: duration.Duration | None = None
    lift_dimension: lift_dimension_1.LiftDimension | 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 attribution_methodology : AttributionMethodology | None
var attribution_window : Duration | None
var completion_source : CompletionSource | None
var lift_dimension : LiftDimension | None
var model_config
var viewability_standard : ViewabilityStandard | None

Inherited members

class CanonicalOptimizationGoal1 (**data: Any)
Expand source code
class CanonicalOptimizationGoal1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['metric'] = 'metric'
    metric: Metric
    standard: viewability_standard.ViewabilityStandard | None = None
    vendor: brand_key.BrandKey | None = None
    reach_unit: reach_unit_1.ReachUnit | None = None
    target_frequency: TargetFrequency | None = None
    view_duration_seconds: Annotated[StrictFloat | None, Field(gt=0.0)] = None
    target: Target | None = None
    priority: 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

Class variables

var kind : Literal['metric']
var metric : Metric
var model_config
var priority : int | None
var reach_unit : ReachUnit | None
var standard : ViewabilityStandard | None
var target : Target | None
var target_frequency : TargetFrequency | None
var vendor : BrandKey | None
var view_duration_seconds : float | None

Inherited members

class CanonicalOptimizationGoal2 (**data: Any)
Expand source code
class CanonicalOptimizationGoal2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['event'] = 'event'
    event_sources: Annotated[list[EventSource], Field(min_length=1)]
    target: Target10 | None = None
    attribution_window: attribution_window_1.AttributionWindow | None = None
    priority: 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

Class variables

var attribution_window : AttributionWindow | None
var event_sources : list[EventSource]
var kind : Literal['adcp.types.domains.core.event']
var model_config
var priority : int | None
var target : Target10 | None

Inherited members

class CanonicalOptimizationGoal3 (**data: Any)
Expand source code
class CanonicalOptimizationGoal3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['vendor_metric'] = 'vendor_metric'
    vendor: brand_key.BrandKey
    metric_id: vendor_metric_id.VendorMetricId
    target: Target11 | None = None
    priority: 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

Class variables

var kind : Literal['vendor_metric']
var metric_id : VendorMetricId
var model_config
var priority : int | None
var target : Target11 | None
var vendor : BrandKey

Inherited members

class CanonicalParameters (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class CanonicalParameters(
    RootModel[
        CanonicalParameters18
        | CanonicalParameters19
        | CanonicalParameters20
        | CanonicalParameters21
        | CanonicalParameters22
        | CanonicalParameters23
        | CanonicalParameters24
        | CanonicalParameters25
        | CanonicalParameters26
        | CanonicalParameters27
        | CanonicalParameters28
        | CanonicalParameters29
        | CanonicalParameters30
        | CanonicalParameters31
        | CanonicalParameters32
        | CanonicalParameters33
    ]
):
    root: Annotated[
        CanonicalParameters18
        | CanonicalParameters19
        | CanonicalParameters20
        | CanonicalParameters21
        | CanonicalParameters22
        | CanonicalParameters23
        | CanonicalParameters24
        | CanonicalParameters25
        | CanonicalParameters26
        | CanonicalParameters27
        | CanonicalParameters28
        | CanonicalParameters29
        | CanonicalParameters30
        | CanonicalParameters31
        | CanonicalParameters32
        | CanonicalParameters33,
        Field(
            description="**DEPRECATED in 3.1. Removed at 4.0.** Use `v1_format_ref` on the v2 `ProductFormatDeclaration` instead — the seller authors a v2 declaration (in `Product.format_options` or `creative.supported_formats`) and links it back to this v1 format via `v1_format_ref: { agent_url, id }`. The directional link from v2 → v1 is the same fact as `canonical_parameters` without the parallel-shape drift surface (v1 file and `canonical_parameters` were two declarations of the same thing; hand-authored, drifting silently).\n\nMigration: every seller currently authoring `canonical_parameters` SHOULD migrate to authoring a v2 declaration on the corresponding product (or capability) with `v1_format_ref` pointing back at this v1 format. v1 files become pure v1 again — no v2-shape mirroring.\n\n*Legacy behavior, retained for 3.1–3.x backward compatibility:* When `canonical` is set, this field carries the full ProductFormatDeclaration that the SDK projects this v1 format into. The `format_kind` MUST equal the `canonical` field value (validators enforce). When set, this is the authoritative source for SDK v1→v2 projection — the registry's structural-match parameter inference is bypassed. SDKs reading 3.1 catalogs MUST continue to honor `canonical_parameters` when present; 4.0+ SDKs MAY reject the field. New code SHOULD NOT emit this field. Seller execution authority is never projected through this deprecated field, so tracker_execution_contract and tracker_execution_contract_digest are forbidden.\n\n**Drift contract (still normative while supported).** Hand-authored `canonical_parameters` MUST satisfy the *narrows* relation against this v1 format's `requirements` and `assets[*]` shape (see canonical-formats.mdx 'Narrows — formal definition'). SDKs that read this v1 file SHOULD lint-time check the equivalence at build/load and emit `FORMAT_PROJECTION_FAILED` if the two disagree.",
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Union[CanonicalParameters18, CanonicalParameters19, CanonicalParameters20, CanonicalParameters21, CanonicalParameters22, CanonicalParameters23, CanonicalParameters24, CanonicalParameters25, CanonicalParameters26, CanonicalParameters27, CanonicalParameters28, CanonicalParameters29, CanonicalParameters30, CanonicalParameters31, CanonicalParameters32, CanonicalParameters33]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : CanonicalParameters18 | CanonicalParameters19 | CanonicalParameters20 | CanonicalParameters21 | CanonicalParameters22 | CanonicalParameters23 | CanonicalParameters24 | CanonicalParameters25 | CanonicalParameters26 | CanonicalParameters27 | CanonicalParameters28 | CanonicalParameters29 | CanonicalParameters30 | CanonicalParameters31 | CanonicalParameters32 | CanonicalParameters33
class CanonicalParameters1 (**data: Any)
Expand source code
class CanonicalParameters1(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image'] = 'image'
    params: image.CanonicalFormatImage

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImage
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters10 (**data: Any)
Expand source code
class CanonicalParameters10(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['sponsored_placement'] = 'sponsored_placement'
    params: sponsored_placement.CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['sponsored_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters11 (**data: Any)
Expand source code
class CanonicalParameters11(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['native_in_feed'] = 'native_in_feed'
    params: native_in_feed.CanonicalFormatNativeInFeed

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['native_in_feed']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatNativeInFeed
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters12 (**data: Any)
Expand source code
class CanonicalParameters12(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['responsive_creative'] = 'responsive_creative'
    params: responsive_creative.CanonicalFormatResponsiveCreative

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['responsive_creative']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatResponsiveCreative
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters13 (**data: Any)
Expand source code
class CanonicalParameters13(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['agent_placement'] = 'agent_placement'
    params: agent_placement.CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['agent_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters14 (**data: Any)
Expand source code
class CanonicalParameters14(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['seller_rendered_stateful_display'] = 'seller_rendered_stateful_display'
    params: seller_rendered_stateful_display.CanonicalFormatSellerRenderedStatefulDisplay

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['seller_rendered_stateful_display']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSellerRenderedStatefulDisplay
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters15 (**data: Any)
Expand source code
class CanonicalParameters15(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['coordinated_placements'] = 'coordinated_placements'
    params: coordinated_placements.CanonicalFormatCoordinatedPlacements

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['coordinated_placements']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatCoordinatedPlacements
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters16 (**data: Any)
Expand source code
class CanonicalParameters16(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['custom'] = 'custom'
    params: Annotated[
        dict[str, Any],
        Field(
            description="Custom shape's params. Validated against the schema fetched from `format_schema.uri` at the cached `format_schema.digest`."
        ),
    ]

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['custom']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : dict[str, typing.Any]
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters17 (**data: Any)
Expand source code
class CanonicalParameters17(AdCPBaseModel):
    pass

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 model_config

Inherited members

class CanonicalParameters18 (**data: Any)
Expand source code
class CanonicalParameters18(CanonicalParameters1, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters19 (**data: Any)
Expand source code
class CanonicalParameters19(CanonicalParameters2, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters2 (**data: Any)
Expand source code
class CanonicalParameters2(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['html5'] = 'html5'
    params: html5.CanonicalFormatHtml5Banner

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['html5']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHtml5Banner
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters20 (**data: Any)
Expand source code
class CanonicalParameters20(CanonicalParameters3, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters21 (**data: Any)
Expand source code
class CanonicalParameters21(CanonicalParameters4, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters22 (**data: Any)
Expand source code
class CanonicalParameters22(CanonicalParameters5, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters23 (**data: Any)
Expand source code
class CanonicalParameters23(CanonicalParameters6, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters24 (**data: Any)
Expand source code
class CanonicalParameters24(CanonicalParameters7, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters25 (**data: Any)
Expand source code
class CanonicalParameters25(CanonicalParameters8, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters26 (**data: Any)
Expand source code
class CanonicalParameters26(CanonicalParameters9, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters27 (**data: Any)
Expand source code
class CanonicalParameters27(CanonicalParameters10, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters28 (**data: Any)
Expand source code
class CanonicalParameters28(CanonicalParameters11, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters29 (**data: Any)
Expand source code
class CanonicalParameters29(CanonicalParameters12, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters3 (**data: Any)
Expand source code
class CanonicalParameters3(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['display_tag'] = 'display_tag'
    params: display_tag.CanonicalFormatDisplayTag

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['display_tag']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDisplayTag
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters30 (**data: Any)
Expand source code
class CanonicalParameters30(CanonicalParameters13, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters31 (**data: Any)
Expand source code
class CanonicalParameters31(CanonicalParameters14, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters32 (**data: Any)
Expand source code
class CanonicalParameters32(CanonicalParameters15, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters33 (**data: Any)
Expand source code
class CanonicalParameters33(CanonicalParameters16, CanonicalParameters17):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CanonicalParameters4 (**data: Any)
Expand source code
class CanonicalParameters4(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image_carousel'] = 'image_carousel'
    params: image_carousel.CanonicalFormatImageCarousel

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image_carousel']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImageCarousel
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters5 (**data: Any)
Expand source code
class CanonicalParameters5(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_hosted'] = 'video_hosted'
    params: video_hosted.CanonicalFormatHostedVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters6 (**data: Any)
Expand source code
class CanonicalParameters6(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_vast'] = 'video_vast'
    params: video_vast.CanonicalFormatVastVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters7 (**data: Any)
Expand source code
class CanonicalParameters7(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_hosted'] = 'audio_hosted'
    params: audio_hosted.CanonicalFormatHostedAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters8 (**data: Any)
Expand source code
class CanonicalParameters8(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_vast'] = 'audio_vast'
    params: audio_vast.CanonicalFormatVastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalParameters9 (**data: Any)
Expand source code
class CanonicalParameters9(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id_1.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_daast'] = 'audio_daast'
    params: audio_daast.CanonicalFormatDaastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_daast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDaastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class CanonicalPerformanceStandard (**data: Any)
Expand source code
class CanonicalPerformanceStandard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    metric: performance_standard_metric.PerformanceStandardMetric
    threshold: Annotated[StrictFloat, Field(ge=0.0, le=1.0)]
    standard: viewability_standard.ViewabilityStandard | None = None
    vendor: brand_key.BrandKey

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 metric : PerformanceStandardMetric
var model_config
var standard : ViewabilityStandard | None
var threshold : float
var vendor : BrandKey

Inherited members

class CanonicalPricingOption (**data: Any)
Expand source code
class CanonicalPricingOption(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pricing_option_id: Annotated[str, Field(min_length=1)]
    pricing_model: PricingModel
    currency: Annotated[str, Field(pattern='^[A-Z]{3}$')]
    fixed_price: Annotated[StrictFloat | None, Field(ge=0.0)] = None
    floor_price: Annotated[StrictFloat | None, Field(ge=0.0)] = None
    price_guidance: price_guidance_1.PriceGuidance | None = None
    min_spend_per_package: Annotated[StrictFloat | None, Field(ge=0.0)] = None
    price_breakdown: price_breakdown_1.PriceBreakdown | None = None
    eligible_adjustments: list[adjustment_kind.PriceAdjustmentKind] | None = None
    parameters: dict[str, Any] | None = None
    event_type: event_type_1.EventType | None = None
    custom_event_name: Annotated[str | None, Field(min_length=1)] = None
    event_source_id: Annotated[str | None, Field(min_length=1)] = None
    commission_rate: Annotated[StrictFloat | None, Field(gt=0.0, le=1.0)] = None
    commission_basis_description: Annotated[str | None, Field(max_length=1000, min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var commission_basis_description : str | None
var commission_rate : float | None
var currency : str
var custom_event_name : str | None
var eligible_adjustments : list[PriceAdjustmentKind] | None
var event_source_id : str | None
var event_type : EventType | None
var fixed_price : float | None
var floor_price : float | None
var min_spend_per_package : float | None
var model_config
var parameters : dict[str, typing.Any] | None
var price_breakdown : PriceBreakdown | None
var price_guidance : PriceGuidance | None
var pricing_model : PricingModel
var pricing_option_id : str

Inherited members

class CanonicalProduct (**data: Any)
Expand source code
class CanonicalProduct(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    product_id: Annotated[str, Field(min_length=1)]
    name: Annotated[str, Field(min_length=1)]
    description: str | None = None
    publisher_properties: Annotated[list[PublisherProperty] | None, Field(min_length=1)] = None
    channels: list[channels_1.MediaChannel] | None = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None, Field(min_length=1)
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None, Field(min_length=1)
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None, Field(min_length=1)
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None, Field(min_length=1)
    ] = None
    format_options: Annotated[
        list[canonical_format_option.CanonicalFormatOption] | None, Field(min_length=1)
    ] = None
    placements: list[canonical_placement.CanonicalProductPlacement] | None = None
    collections: Annotated[
        list[collection_selector.CollectionSelector] | None,
        Field(
            description='Collections available in this product, each referencing collections declared in an adagents.json by domain and explicit collection_ids. The domain-only bulk-grant selector form is for authorization scoping, not product composition. A selected-mode collection_selection names collections from this set.',
            min_length=1,
        ),
    ] = None
    collection_targeting_allowed: Annotated[
        StrictBool | None,
        Field(
            description="Whether buyers can select a subset of this product's collections through targeting_overlay.collection_list or targeting_overlay.collection_selection. When false, the product is a fixed bundle (a collection_selection that exactly restates the complete bundle remains an inherent match)."
        ),
    ] = False
    delivery_type: delivery_type_1.DeliveryType | None = None
    exclusivity: exclusivity_1.Exclusivity | None = None
    pricing_options: Annotated[
        list[canonical_pricing_option.CanonicalPricingOption] | None, Field(min_length=1)
    ] = None
    forecast: canonical_delivery_forecast.CanonicalDeliveryForecast | None = None
    reporting_capabilities: (
        canonical_reporting_capabilities.CanonicalReportingCapabilities | None
    ) = None
    measurement_terms: Annotated[
        canonical_measurement_terms.CanonicalMeasurementTerms | None,
        Field(
            description='Default billing measurement and makegood terms inherited by a direct purchase unless a negotiated proposal replaces them.'
        ),
    ] = None
    performance_standards: Annotated[
        list[canonical_performance_standard.CanonicalPerformanceStandard] | None,
        Field(
            description='Default performance thresholds and measurement vendors inherited by a direct purchase.',
            min_length=1,
        ),
    ] = None
    catalog_types: Annotated[list[catalog_type.CatalogType] | None, Field(min_length=1)] = None
    signal_targeting_allowed: StrictBool | None = None
    signal_targeting_rules: signal_targeting_rules_1.SignalTargetingRules | None = None
    demographic_targeting: (
        demographic_targeting_capability.DemographicTargetingCapability | None
    ) = None
    overlay_support: Annotated[
        targeting_overlay_support.TargetingOverlaySupport | None,
        Field(
            description='Binding product-scoped targeting dimensions the buyer may set independently on a package after discovery.'
        ),
    ] = None
    media_buy_support: Annotated[
        media_buy_support_1.ProductMediaBuySupport | None,
        Field(description='Binding product participation in shared MediaBuy-level controls.'),
    ] = None
    identity: Annotated[
        product_identity.ProductIdentity | None,
        Field(
            description='Experimental product-scoped identity and reach-measurement facts. See Product.identity for the cross-object delivery and frequency-cap rules.'
        ),
    ] = None
    execution_requirements: Annotated[
        list[product_execution_requirement.ProductExecutionRequirement] | None,
        Field(
            description='Experimental account resources a package on this product needs before it can be created. See Product.execution_requirements for completeness, binding, and rejection rules.',
            min_length=1,
        ),
    ] = None
    audience_evidence: Annotated[
        list[canonical_audience_evidence.CanonicalAudienceEvidence] | None, Field(min_length=1)
    ] = None
    audience_evidence_selections: Annotated[
        list[canonical_audience_evidence_selection.CanonicalAudienceEvidenceSelection] | None,
        Field(
            description='Exact evidence snapshots that affected eligibility or ranking. Returned whenever evidence requirements affected the result, even if not requested explicitly.',
            min_length=1,
        ),
    ] = None
    max_optimization_goals: Annotated[SchemaInt | None, Field(ge=0)] = None
    catalog_match: CatalogMatch | None = None
    list_applications: Annotated[
        list[inventory_list_application.InventoryListApplication] | None,
        Field(
            description='Product-scoped receipts for every effective property- or collection-list targeting reference. Sellers MUST return one receipt per application regardless of response field projection; exclusion applications receive a receipt even when summary.matched is zero, while zero matches for any inclusion application make the product ineligible and it is not returned. Each receipt uses the same pre-list product inventory baseline; pricing and forecast reflect inventory remaining after all effective lists are composed.',
            min_length=1,
        ),
    ] = None
    brief_relevance: str | None = None
    targeting_resolution: Annotated[
        product_targeting_resolution.ProductTargetingResolution | None,
        Field(
            description='Discovery-time targeting resolution bound to this configured product. modifications sparsely disclose product-specific differences from criteria.targeting_overlay; absence means exact acceptance of the structured overlay. Request-level brief interpretation is returned once on the response-root targeting_resolution. Selecting product_id accepts the disclosed modifications; pricing and forecast MUST reflect them. Requires expires_at.'
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Expiration of a request-specific configured offer. Canonical products have no is_custom flag; expires_at is what marks an offer as request-specific. After it, the buyer rediscovers.'
        ),
    ] = None
    allowed_actions: list[canonical_product_action.CanonicalProductAction] | None = None
    acceptance_policy_profile_ids: (
        acceptance_policy_profile_ids_1.AcceptancePolicyProfileIds | None
    ) = None
    ext: ext_1.ExtensionObject | 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 acceptance_policy_profile_ids : AcceptancePolicyProfileIds | None
var allowed_actions : list[CanonicalProductAction] | None
var audience_evidence : list[CanonicalAudienceEvidence] | None
var audience_evidence_selections : list[CanonicalAudienceEvidenceSelection] | None
var audio_distribution_types : list[AudioDistributionType] | None
var brief_relevance : str | None
var catalog_match : CatalogMatch | None
var catalog_types : list[CatalogType] | None
var channels : list[MediaChannel] | None
var collection_targeting_allowed : bool | None
var collections : list[CollectionSelector] | None
var delivery_type : DeliveryType | None
var demographic_targeting : DemographicTargetingCapability | None
var description : str | None
var exclusivity : Exclusivity | None
var execution_requirements : list[ProductExecutionRequirement1 | ProductExecutionRequirement2 | ProductExecutionRequirement3] | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var forecast : CanonicalDeliveryForecast | None
var format_options : list[CanonicalFormatOption] | None
var identity : ProductIdentity | None
var list_applications : list[InventoryListApplication1 | InventoryListApplication2] | None
var max_optimization_goals : int | None
var measurement_terms : CanonicalMeasurementTerms | None
var media_buy_support : ProductMediaBuySupport | None
var model_config
var name : str
var overlay_support : TargetingOverlaySupport | None
var performance_standards : list[CanonicalPerformanceStandard] | None
var placements : list[CanonicalProductPlacement1 | CanonicalProductPlacement2] | None
var pricing_options : list[CanonicalPricingOption] | None
var product_id : str
var publisher_properties : list[PublisherProperty5 | PublisherProperty6 | PublisherProperty7] | None
var reporting_capabilities : CanonicalReportingCapabilities | None
var signal_targeting_allowed : bool | None
var signal_targeting_rules : SignalTargetingRules | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var targeting_resolution : ProductTargetingResolution | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class CanonicalProductAction (**data: Any)
Expand source code
class CanonicalProductAction(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    action: canonical_media_buy_action.CanonicalMediaBuyActionName
    modes: Annotated[
        list[canonical_media_buy_action_mode.CanonicalMediaBuyActionMode], Field(min_length=1)
    ]
    allowed_statuses: Annotated[
        list[media_buy_status.MediaBuyStatus] | None, Field(min_length=1)
    ] = None
    sla: sla_window.SlaWindow | None = None
    constraints: Annotated[
        change_term_constraints.MediaBuyChangeTermConstraints | None,
        Field(
            description='Advisory machine-readable bounds for product selection; proposal change terms restate binding bounds.'
        ),
    ] = None
    terms_ref: Annotated[
        str | None,
        Field(
            description='Optional advisory pointer to published commercial terms. It is not a proposal change-term identity.'
        ),
    ] = 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 action : CanonicalMediaBuyActionName
var allowed_statuses : list[MediaBuyStatus] | None
var constraints : MediaBuyChangeTermConstraints1 | MediaBuyChangeTermConstraints2 | MediaBuyChangeTermConstraints3 | MediaBuyChangeTermConstraints4 | None
var model_config
var modes : list[CanonicalMediaBuyActionMode]
var sla : SlaWindow | None
var terms_ref : str | None

Inherited members

class CanonicalProductPlacement1 (**data: Any)
Expand source code
class CanonicalProductPlacement1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['publisher_ref'] = 'publisher_ref'
    placement_id: Annotated[str, Field(min_length=1)]
    publisher_domain: Annotated[
        str,
        Field(
            description='For publisher_ref, the adagents.json publisher namespace. For seller_inline, optional inventory-publisher attribution only.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    seller_agent: Annotated[
        seller_agent_ref.SellerAgentReference | None,
        Field(
            description='Defining sales agent for seller_inline identity. Recommended for new declarations; optional only to preserve legacy product-context placements.'
        ),
    ] = None
    name: Annotated[str | None, Field(min_length=1)] = None
    description: str | None = None
    mode: Mode
    tags: list[str] | None = None
    format_options: Annotated[
        list[canonical_format_option.CanonicalFormatOption] | None, Field(min_length=1)
    ] = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None, Field(min_length=1)
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None, Field(min_length=1)
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None, Field(min_length=1)
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None, Field(min_length=1)
    ] = None
    identifiers: Annotated[
        list[Identifier] | None,
        Field(
            description='Optional external inventory identifiers for this placement. Externally governed values should be authority-prefixed; seller-local values are scoped by the surrounding publisher namespace. For publisher_ref placements, the effective set is the union of publisher and product declarations, de-duplicated by exact (type, value).',
            min_length=1,
        ),
    ] = None
    dooh_placement_attributes: CanonicalDoohPlacementAttributes | 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 audio_distribution_types : list[AudioDistributionType] | None
var description : str | None
var dooh_placement_attributes : CanonicalDoohPlacementAttributes | None
var format_options : list[CanonicalFormatOption] | None
var identifiers : list[Identifier] | None
var kind : Literal['publisher_ref']
var mode : Mode
var model_config
var name : str | None
var placement_id : str
var publisher_domain : str
var seller_agent : SellerAgentReference | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var tags : list[str] | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class CanonicalProductPlacement2 (**data: Any)
Expand source code
class CanonicalProductPlacement2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['seller_inline'] = 'seller_inline'
    placement_id: Annotated[str, Field(min_length=1)]
    publisher_domain: Annotated[
        str | None,
        Field(
            description='For publisher_ref, the adagents.json publisher namespace. For seller_inline, optional inventory-publisher attribution only.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    seller_agent: Annotated[
        seller_agent_ref.SellerAgentReference | None,
        Field(
            description='Defining sales agent for seller_inline identity. Recommended for new declarations; optional only to preserve legacy product-context placements.'
        ),
    ] = None
    name: Annotated[str, Field(min_length=1)]
    description: str | None = None
    mode: Mode
    tags: list[str] | None = None
    format_options: Annotated[
        list[canonical_format_option.CanonicalFormatOption] | None, Field(min_length=1)
    ] = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None, Field(min_length=1)
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None, Field(min_length=1)
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None, Field(min_length=1)
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None, Field(min_length=1)
    ] = None
    identifiers: Annotated[
        list[Identifier] | None,
        Field(
            description='Optional external inventory identifiers for this placement. Externally governed values should be authority-prefixed; seller-local values are scoped by the surrounding publisher namespace. For publisher_ref placements, the effective set is the union of publisher and product declarations, de-duplicated by exact (type, value).',
            min_length=1,
        ),
    ] = None
    dooh_placement_attributes: CanonicalDoohPlacementAttributes | 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 audio_distribution_types : list[AudioDistributionType] | None
var description : str | None
var dooh_placement_attributes : CanonicalDoohPlacementAttributes | None
var format_options : list[CanonicalFormatOption] | None
var identifiers : list[Identifier] | None
var kind : Literal['seller_inline']
var mode : Mode
var model_config
var name : str
var placement_id : str
var publisher_domain : str | None
var seller_agent : SellerAgentReference | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var tags : list[str] | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class CanonicalProjectionReference (**data: Any)
Expand source code
class CanonicalProjectionReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Annotated[
        str,
        Field(
            description='The v2 canonical-format-kind this v1 format projects to (`image`, `html5`, `display_tag`, `image_carousel`, `video_hosted`, `video_vast`, `audio_hosted`, `audio_vast`, `audio_daast`, `sponsored_placement`, `native_in_feed`, `responsive_creative`, `agent_placement`, `seller_rendered_stateful_display`, `coordinated_placements`, or `custom`).'
        ),
    ]
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description="Where the rendered asset bytes come from on the projected v2 declaration. Default (when omitted) is `buyer_uploaded` — the canonical's default. Set explicitly when the v1 named format doesn't follow that default. Required for generative entries (`agent_synthesized` or `seller_pre_rendered_from_brief`) because their asset shape doesn't carry image/video/audio bytes, and for published-post reference entries (`publisher_owned_reference`) because their asset shape carries a post reference rather than uploaded bytes. Projection without this hint produces a lossy v2 declaration that claims buyer-uploaded bytes."
        ),
    ] = None
    slots_override: Annotated[
        list[canonical_projection_slot_override.CanonicalProjectionSlotOverride] | None,
        Field(
            description="When the v1 named format's slot shape differs from the canonical's default slots, this carries the override that the projected v2 declaration's `params.slots[]` should use. REPLACES (does not merge with) the canonical's default slots — projection-time semantics. The slot vocabulary follows `asset-group-vocabulary.json`. Asset IDs in the v1 format's `assets[*]` MUST resolve (directly or via the vocabulary's aliases) to the `asset_group_id` values declared here.",
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_source : AssetSource | None
var kind : str
var model_config
var slots_override : list[CanonicalProjectionSlotOverride] | None

Inherited members

class CanonicalProjectionSlotOverride (**data: Any)
Expand source code
class CanonicalProjectionSlotOverride(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_group_id: Annotated[
        str,
        Field(
            description='Asset group identifier from `asset-group-vocabulary.json` (e.g., `generation_prompt`, `creative_brief`, `image_main`, `video_main`).'
        ),
    ]
    asset_type: Annotated[
        str,
        Field(
            description='Asset type — `image`, `video`, `audio`, `text`, `html`, `javascript`, `url`, `zip`, `brief`, `catalog`, `published_post`, or another canonical slot asset type.'
        ),
    ]
    required: Annotated[
        StrictBool | None,
        Field(description='Whether the slot is required in the projected declaration.'),
    ] = False
    max_chars: Annotated[
        SchemaInt | None, Field(description='Max character count for text slots.', ge=1)
    ] = None
    consumed_for_production: Annotated[
        StrictBool | None,
        Field(
            description="When false, slot is for moderation/review only and is NOT consumed by the seller's renderer (e.g., a brand-safety brief that informs review but doesn't appear in the rendered ad)."
        ),
    ] = True

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 : str
var consumed_for_production : bool | None
var max_chars : int | None
var model_config
var required : bool | None

Inherited members

class CanonicalProposal (**data: Any)
Expand source code
class CanonicalProposal(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    proposal_id: Annotated[str, Field(max_length=255, min_length=1)]
    proposal_kind: ProposalKind
    parent_proposal_id: Annotated[
        str | None,
        Field(
            description="Immediate predecessor this snapshot was forked from. Every proposal produced by refine_proposals carries it, equal to the request's source proposal_id, so negotiation lineage is reconstructible from proposals alone.",
            max_length=255,
            min_length=1,
        ),
    ] = None
    media_buy_id: Annotated[str | None, Field(min_length=1)] = None
    opportunity_id: Annotated[
        str | None,
        Field(
            description='Buyer planning cycle associated with this proposal. Revisions inherit it; it does not participate in proposal identity.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    base_media_buy_revision: Annotated[SchemaInt | None, Field(ge=1)] = None
    proposal_status: Annotated[
        proposal_status_1.ProposalStatus,
        Field(
            description='draft is indicative and unreserved; committed has firm terms with inventory reserved until expires_at; accepted is the historical snapshot attached to a MediaBuy.'
        ),
    ]
    accepted_at: AwareDatetime | None = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='For a draft, the indicative-terms freshness deadline. For a committed proposal, the inventory-hold deadline.'
        ),
    ] = None
    name: Annotated[str, Field(max_length=500, min_length=1)]
    description: Annotated[str | None, Field(max_length=2000)] = None
    brief_alignment: Annotated[str | None, Field(max_length=2000)] = None
    commercial_terms: commercial_terms_1.CommercialTerms
    terms_digest: Annotated[
        str,
        Field(
            description='Base64url SHA-256 digest of the RFC 8785 JCS serialization of commercial_terms, prefixed with sha256:.',
            pattern='^sha256:[A-Za-z0-9_-]{43}$',
        ),
    ]
    insertion_order: insertion_order_1.InsertionOrder | None = None
    total_budget_guidance: Annotated[
        TotalBudgetGuidance | None,
        Field(
            description="Optional budget guidance for this proposal — the planning answer to criteria.outcome_target and to open-budget briefs. commercial_terms_1.total_budget remains the concrete figure the plan is priced at; this band expresses the seller's recommended range around it. When criteria.outcome_target carries cost_per, the cost answer is commercial_terms_1.bidding.cost_per and this band's currency equals cost_per.currency."
        ),
    ] = None
    forecast: Annotated[
        canonical_delivery_forecast.CanonicalDeliveryForecast | None,
        Field(
            description="Aggregate forecasted delivery for the proposal. For outcome_target requests, points carry the goal's metric or event key in metrics; with cost_per, that is the goal volume planned under the commercial_terms_1.bidding policy, and currency equals cost_per.currency."
        ),
    ] = 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 accepted_at : pydantic.types.AwareDatetime | None
var base_media_buy_revision : int | None
var brief_alignment : str | None
var commercial_terms : CommercialTerms
var description : str | None
var expires_at : pydantic.types.AwareDatetime | None
var forecast : CanonicalDeliveryForecast | None
var insertion_order : InsertionOrder | None
var media_buy_id : str | None
var model_config
var name : str
var opportunity_id : str | None
var parent_proposal_id : str | None
var proposal_id : str
var proposal_kind : ProposalKind
var proposal_status : ProposalStatus
var terms_digest : str
var total_budget_guidance : TotalBudgetGuidance | None

Inherited members

class CanonicalReportingCapabilities (**data: Any)
Expand source code
class CanonicalReportingCapabilities(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    available_reporting_frequencies: Annotated[
        list[reporting_frequency.ReportingFrequency], Field(min_length=1)
    ]
    expected_delay_minutes: Annotated[SchemaInt, Field(ge=0)]
    timezone: Annotated[
        str,
        Field(
            description='Explicit reporting-period timezone for this product. It may equal Account.timezone or differ when the upstream platform reports on a separate boundary.'
        ),
    ]
    supports_webhooks: StrictBool
    reporting_delivery_offering_ids: Annotated[
        list[reporting_delivery_offering_id.ReportingDeliveryOfferingId] | None,
        Field(
            description='Product-scoped subset of get_adcp_capabilities.media_buy.reporting_delivery.offerings[].offering_id that packages using this product can satisfy. This binds seller-wide managed-delivery offerings to product/package eligibility. An empty array explicitly declares no managed offering; absence means product-level applicability is unknown and MUST NOT be inferred from the seller-wide list. Account, seat, credential, or provider constraints may narrow support further during sync_accounts validation.'
        ),
    ] = None
    available_metrics: list[available_metric.AvailableMetric]
    vendor_metrics: list[VendorMetric] | None = None
    supports_creative_breakdown: StrictBool | None = None
    supports_format_breakdown: StrictBool | None = None
    supports_keyword_breakdown: StrictBool | None = None
    supports_geo_breakdown: geo_breakdown_support.GeographicBreakdownSupport | None = None
    supports_device_type_breakdown: StrictBool | None = None
    supports_device_platform_breakdown: StrictBool | None = None
    supports_audience_breakdown: StrictBool | None = None
    supports_demographic_breakdown: (
        demographic_reporting_capability.DemographicReportingCapability | None
    ) = None
    supports_placement_breakdown: StrictBool | None = None
    supports_property_breakdown: StrictBool | None = None
    supports_collection_breakdown: StrictBool | None = None
    supports_installment_breakdown: StrictBool | None = None
    supports_collection_property_breakdown: StrictBool | None = None
    supports_installment_property_breakdown: StrictBool | None = None
    supports_placement_property_breakdown: StrictBool | None = None
    supports_spot_breakdown: spot_reporting_capability.SpotReportingCapability | None = None
    date_range_support: DateRangeSupport
    windowed_pull_granularities: list[reporting_frequency.ReportingFrequency] | None = None
    measurement_windows: Annotated[
        list[measurement_window.MeasurementWindow] | None, Field(min_length=1)
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var available_metrics : list[AvailableMetric]
var available_reporting_frequencies : list[ReportingFrequency]
var date_range_support : DateRangeSupport
var expected_delay_minutes : int
var measurement_windows : list[MeasurementWindow] | None
var model_config
var reporting_delivery_offering_ids : list[ReportingDeliveryOfferingId] | None
var supports_audience_breakdown : bool | None
var supports_collection_breakdown : bool | None
var supports_collection_property_breakdown : bool | None
var supports_creative_breakdown : bool | None
var supports_demographic_breakdown : DemographicReportingCapability | None
var supports_device_platform_breakdown : bool | None
var supports_device_type_breakdown : bool | None
var supports_format_breakdown : bool | None
var supports_geo_breakdown : GeographicBreakdownSupport | None
var supports_installment_breakdown : bool | None
var supports_installment_property_breakdown : bool | None
var supports_keyword_breakdown : bool | None
var supports_placement_breakdown : bool | None
var supports_placement_property_breakdown : bool | None
var supports_property_breakdown : bool | None
var supports_spot_breakdown : SpotReportingCapability | None
var supports_webhooks : bool
var timezone : str
var vendor_metrics : list[VendorMetric] | None
var windowed_pull_granularities : list[ReportingFrequency] | None

Inherited members

class CanonicalReportingCommitment1 (**data: Any)
Expand source code
class CanonicalReportingCommitment1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['standard'] = 'standard'
    metric_id: available_metric.AvailableMetric
    qualifier: canonical_metric_qualifier.CanonicalMetricQualifier | None = None
    effective_at: AwareDatetime | 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 effective_at : pydantic.types.AwareDatetime | None
var metric_id : AvailableMetric
var model_config
var qualifier : CanonicalMetricQualifier | None
var scope : Literal['standard']

Inherited members

class CanonicalReportingCommitment2 (**data: Any)
Expand source code
class CanonicalReportingCommitment2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['vendor'] = 'vendor'
    vendor: brand_key.BrandKey
    metric_id: vendor_metric_id.VendorMetricId
    qualifier: canonical_metric_qualifier.CanonicalMetricQualifier | None = None
    effective_at: AwareDatetime | 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 effective_at : pydantic.types.AwareDatetime | None
var metric_id : VendorMetricId
var model_config
var qualifier : CanonicalMetricQualifier | None
var scope : Literal['vendor']
var vendor : BrandKey

Inherited members

class Canvas (**data: Any)
Expand source code
class Canvas(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    width: Annotated[SchemaInt, Field(ge=1, le=8192)]
    height: Annotated[SchemaInt, Field(ge=1, le=8192)]
    background_color: Annotated[str | None, Field(pattern='^#[0-9A-Fa-f]{6}$')] = '#ffffff'

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 background_color : str | None
var height : int
var model_config
var width : int

Inherited members

class CanvasConstraint (**data: Any)
Expand source code
class CanvasConstraint(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    constraint: Constraint
    state_id: Annotated[str | None, Field(pattern='^[a-z][a-z0-9_]*$')] = None
    breakpoint_id: Annotated[str | None, Field(pattern='^[a-z][a-z0-9_]*$')] = None
    region: Region

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 breakpoint_id : str | None
var constraint : Constraint
var model_config
var region : Region
var state_id : str | None

Inherited members

class CapabilitiesChangedWebhook (**data: Any)
Expand source code
class CapabilitiesChangedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Sender-generated key stable across retries of the same fire. Sellers MUST generate a cryptographically random value (UUID v4 recommended) per distinct fire and reuse it on every retry of the same fire. Receivers MUST dedupe by this key, scoped to the authenticated sender identity.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Stable identifier for this logical capability-change event. Re-emissions of the same logical change reuse this value under a new idempotency_key; a later material capability revision receives a new id.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Annotated[
        Literal['capabilities.changed'],
        Field(
            description="Fixed notification type discriminator. Matches the value registered on the subscriber's `event_types`."
        ),
    ] = 'capabilities.changed'
    fired_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller initiated this fire. Distinct from `changed_at`, which is when the seller recorded the material capability change.'
        ),
    ]
    subscriber_id: Annotated[
        str,
        Field(
            description="Identifies which caller-scoped notification_configs[] entry is receiving this fire. Echoed verbatim from the entry's subscriber_id.",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='Canonical seller agent URL whose capabilities changed. Receivers that subscribe to multiple agents use this to select the cache entry to invalidate.'
        ),
    ]
    changed_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller recorded the material capability change. SHOULD match or precede `adcp.capability_changes.last_modified` on the next `get_adcp_capabilities` response.'
        ),
    ]
    reason: Annotated[
        Reason,
        Field(
            description='Coarse reason for the invalidation. This is advisory routing/debug metadata; receivers MUST re-read `get_adcp_capabilities` rather than relying on the reason to infer the new capability surface.'
        ),
    ]
    capabilities_version: Annotated[
        str,
        Field(
            description='Required opaque revision token for the capability document after the change. MUST equal `adcp.capability_changes.capabilities_version` on the authoritative `get_adcp_capabilities` response available before this webhook is sent. Receivers MUST treat the token as opaque and compare it only for equality.',
            max_length=255,
            min_length=1,
        ),
    ]
    changed_paths: Annotated[
        list[ChangedPath] | None,
        Field(
            description='Optional advisory JSON Pointer-style paths that identify the top-level or nested capability subtrees that changed (for example `/account/sandbox` or `/supported_protocols`). Receivers MAY use this for logging or selective downstream invalidation, but MUST still treat the full `get_adcp_capabilities` response as the authoritative replacement snapshot.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 agent_url : pydantic.networks.AnyUrl
var capabilities_version : str
var changed_at : pydantic.types.AwareDatetime
var changed_paths : list[ChangedPath] | None
var ext : ExtensionObject | None
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var model_config
var notification_id : str
var notification_type : Literal['capabilities.changed']
var reason : Reason
var subscriber_id : str

Inherited members

class CatalogFieldBinding1 (**data: Any)
Expand source code
class CatalogFieldBinding1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['catalog_group'] = 'catalog_group'
    format_group_id: Annotated[
        str,
        Field(description="The asset_group_id of a repeatable_group in the format's assets array."),
    ]
    catalog_item: Annotated[
        Literal[True],
        Field(
            description="Each repetition of the format's repeatable_group maps to one item from the catalog."
        ),
    ]
    per_item_bindings: Annotated[
        list[PerItemBindings] | None,
        Field(
            description='Scalar and asset pool bindings that apply within each repetition of the group. Nested catalog_group bindings are not permitted.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 catalog_item : Literal[True]
var ext : ExtensionObject | None
var format_group_id : str
var kind : Literal['catalog_group']
var model_config
var per_item_bindings : list[ScalarBinding | AssetPoolBinding] | None

Inherited members

class CatalogItemAvailabilityError (**data: Any)
Expand source code
class CatalogItemAvailabilityError(Error):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class CatalogItemAvailabilityReference (**data: Any)
Expand source code
class CatalogItemAvailabilityReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_id: Annotated[
        str, Field(description='Buyer-assigned catalog ID.', max_length=255, min_length=1)
    ]
    catalog_generation: Annotated[
        str,
        Field(
            description='Opaque seller-issued token for the referenced catalog incarnation. It remains stable across ordinary upserts and feed refreshes, changes when a deleted catalog_id is recreated, and MUST never be reused for that account and catalog_id.',
            max_length=255,
            min_length=1,
        ),
    ]
    item_id: Annotated[
        str,
        Field(
            description='Exact canonical item key used by Catalog.ids. For typed catalogs this is the type-specific identifier field; for product, inventory, and promotion catalogs it is the stable normalized source identifier retained during ingestion.',
            max_length=255,
            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 catalog_generation : str
var catalog_id : str
var item_id : str
var model_config

Inherited members

class CatalogItemAvailabilityState (**data: Any)
Expand source code
class CatalogItemAvailabilityState(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    request_index: Annotated[
        SchemaInt,
        Field(
            description='Zero-based index of the corresponding item_availability_queries entry.',
            ge=0,
        ),
    ]
    catalog_id: Annotated[str, Field(max_length=255, min_length=1)]
    catalog_generation: Annotated[str, Field(max_length=255, min_length=1)]
    item_id: Annotated[str, Field(max_length=255, min_length=1)]
    status: Annotated[
        Status,
        Field(
            description='found returns current state; failed means the reference could not be read.'
        ),
    ]
    availability: Annotated[
        Availability | None,
        Field(
            description='Current buyer-authored overlay state. active does not imply seller approval or delivery eligibility.'
        ),
    ] = None
    overlay_revision: Annotated[
        SchemaInt | None,
        Field(
            description='Current optimistic-concurrency token. Revision 0 is the initial active state. Every applied suppress, applied restore, and automatic expiry increments it exactly once; unchanged updates, reads, and idempotent replays do not increment it.',
            ge=0,
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Current automatic expiry, present only while availability is suppressed with an expiry.'
        ),
    ] = None
    updated_at: Annotated[
        AwareDatetime | None,
        Field(description='Seller timestamp of the state represented by overlay_revision.'),
    ] = None
    errors: Annotated[
        list[catalog_item_availability_error.CatalogItemAvailabilityError] | None,
        Field(min_length=1),
    ] = None
    ext: ext_1.ExtensionObject | 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 availability : Availability | None
var catalog_generation : str
var catalog_id : str
var errors : list[CatalogItemAvailabilityError] | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var item_id : str
var model_config
var overlay_revision : int | None
var request_index : int
var status : Status
var updated_at : pydantic.types.AwareDatetime | None

Inherited members

class CatalogItemAvailabilityUpdate (**data: Any)
Expand source code
class CatalogItemAvailabilityUpdate(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_id: Annotated[
        str,
        Field(
            description='Buyer-assigned ID of the buyer-managed catalog containing the item.',
            max_length=255,
            min_length=1,
        ),
    ]
    catalog_generation: Annotated[
        str,
        Field(
            description='Opaque seller-issued token for the catalog incarnation. Obtain it from sync_catalogs discovery or mutation results. A generation mismatch is treated as REFERENCE_NOT_FOUND, preventing a delayed update from affecting a deleted-and-recreated catalog.',
            max_length=255,
            min_length=1,
        ),
    ]
    item_id: Annotated[
        str,
        Field(
            description='Exact canonical item key used by Catalog.ids. For typed catalogs this is the type-specific identifier field; for product, inventory, and promotion catalogs it is the stable normalized source identifier retained during ingestion.',
            max_length=255,
            min_length=1,
        ),
    ]
    expected_overlay_revision: Annotated[
        SchemaInt,
        Field(
            description='Required optimistic-concurrency token obtained from item_availability_states. Revision 0 is the initial active state. The seller MUST compare this value atomically with the write and return CONFLICT without mutation when it differs from current state.',
            ge=0,
        ),
    ]
    action: Annotated[
        Action,
        Field(
            description='suppress makes the item and known derived creative variants ineligible immediately; restore removes the buyer-authored suppression but does not bypass seller controls.'
        ),
    ]
    reason: Annotated[
        Reason,
        Field(
            description='Machine-readable reason for the transition. Use other only when no standard reason applies and explain the condition in reason_detail.'
        ),
    ]
    reason_detail: Annotated[
        str | None,
        Field(
            description='Optional human-readable context. Required when reason is other. Plain text only; receivers MUST treat it as untrusted buyer input.',
            max_length=1000,
            min_length=1,
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Optional expiry for a suppress overlay. At this instant the seller automatically removes the buyer-authored suppression as if it received restore. Valid only with action suppress; omit for an indefinite suppression. Sellers MUST reject a timestamp that is not in the future when the request is processed. On a repeated suppress, this value is complete replacement state: a changed timestamp replaces the prior expiry, and omission clears a prior expiry to make suppression indefinite. Either change returns status applied, not unchanged.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 action : Action
var catalog_generation : str
var catalog_id : str
var expected_overlay_revision : int
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var item_id : str
var model_config
var reason : Reason
var reason_detail : str | None

Inherited members

class CatalogItemAvailabilityUpdateResult (**data: Any)
Expand source code
class CatalogItemAvailabilityUpdateResult(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    request_index: Annotated[
        SchemaInt,
        Field(
            description='Zero-based index of the corresponding item_availability_updates entry.',
            ge=0,
        ),
    ]
    catalog_id: Annotated[str, Field(description='Catalog ID from the request.')]
    catalog_generation: Annotated[
        str, Field(description='Catalog generation from the request.', max_length=255, min_length=1)
    ]
    item_id: Annotated[str, Field(description='Item ID from the request.')]
    action: Annotated[Action, Field(description='Action from the request.')]
    status: Annotated[
        Status,
        Field(
            description='applied means the requested overlay transition completed, including replacement or removal of an existing expires_at; unchanged means the item was already in the requested buyer-availability state with the same expiry; failed means no transition was applied.'
        ),
    ]
    availability: Annotated[
        Availability | None,
        Field(description='Persisted buyer-authored state after an applied or unchanged result.'),
    ] = None
    overlay_revision: Annotated[
        SchemaInt | None,
        Field(
            description="Persisted state revision after an applied or unchanged result. Applied increments the request's expected_overlay_revision exactly once; unchanged preserves it.",
            ge=0,
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Persisted expiry after this update, present only for a suppressed state with an expiry.'
        ),
    ] = None
    applied_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Seller timestamp when the buyer-availability state took effect. Required for applied. Optional for unchanged when the seller knows the timestamp of the already-persisted state.'
        ),
    ] = None
    errors: Annotated[
        list[catalog_item_availability_error.CatalogItemAvailabilityError] | None,
        Field(
            description='Why this item update failed. Required when status is failed.', min_length=1
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 action : Action
var applied_at : pydantic.types.AwareDatetime | None
var availability : Availability | None
var catalog_generation : str
var catalog_id : str
var errors : list[CatalogItemAvailabilityError] | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var item_id : str
var model_config
var overlay_revision : int | None
var request_index : int
var status : Status

Inherited members

class CatalogItemDeliveryMetrics (**data: Any)
Expand source code
class CatalogItemDeliveryMetrics(DeliveryMetrics):
    content_id: Annotated[
        str, Field(description='Catalog item identifier (e.g., SKU, GTIN, job_id, offering_id)')
    ]
    content_id_type: Annotated[
        content_id_type_1.ContentIdType | None,
        Field(description='Identifier type for this content_id'),
    ] = None
    impressions: Any
    spend: Any

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 content_id : str
var content_id_type : ContentIdType | None
var impressions : Any
var model_config
var spend : Any

Inherited members

class CatalogItemReferenceNotFoundError (**data: Any)
Expand source code
class CatalogItemReferenceNotFoundError(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    code: Literal['REFERENCE_NOT_FOUND'] = 'REFERENCE_NOT_FOUND'
    message: Literal['Catalog item not found'] = 'Catalog item not found'
    recovery: Literal['correctable'] = 'correctable'

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 code : Literal['REFERENCE_NOT_FOUND']
var message : Literal['Catalog item not found']
var model_config
var recovery : Literal['correctable']

Inherited members

class CatalogRequirement (**data: Any)
Expand source code
class CatalogRequirement(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    countries: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[A-Z]{2}$')], list[geo_place_type.GeographicPlaceType]],
        Field(min_length=1),
    ]
    system_versions: Annotated[
        list[SystemVersion] | None,
        Field(
            description='Optional exact catalog versions that must remain selectable. Versions are opaque strings, not ordered ranges.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var countries : dict[str, list[GeographicPlaceType1 | GeographicPlaceType2]]
var model_config
var system_versions : list[SystemVersion] | None

Inherited members

class CatalogRequirements (**data: Any)
Expand source code
class CatalogRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_type: Annotated[
        catalog_type_1.CatalogType,
        Field(description='The catalog type this requirement applies to'),
    ]
    required: Annotated[
        StrictBool | None,
        Field(
            description='Whether this catalog type must be present. When true, creatives using this format must reference a synced catalog of this type.'
        ),
    ] = True
    min_items: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum number of items the catalog must contain for this format to render properly (e.g., a carousel might require at least 3 products)',
            ge=1,
        ),
    ] = None
    max_items: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of items the format can render. Items beyond this limit are ignored. Useful for fixed-slot layouts (e.g., a 3-product card) or feed-size constraints.',
            ge=1,
        ),
    ] = None
    required_fields: Annotated[
        list[str] | None,
        Field(
            description="Fields that must be present and non-empty on every item in the catalog. Field names are catalog-type-specific (e.g., 'title', 'price', 'image_url' for product catalogs; 'store_id', 'quantity' for inventory feeds).",
            min_length=1,
        ),
    ] = None
    feed_formats: Annotated[
        list[feed_format.FeedFormat] | None,
        Field(
            description='Accepted feed formats for this catalog type. When specified, the synced catalog must use one of these formats. When omitted, any format is accepted.',
            min_length=1,
        ),
    ] = None
    offering_asset_constraints: Annotated[
        list[offering_asset_constraint.OfferingAssetConstraint] | None,
        Field(
            description="Per-item creative asset requirements. Declares what asset groups (headlines, images, videos) each catalog item must provide in its assets array, along with count bounds and per-asset technical constraints. Applicable to 'offering' and all vertical catalog types (hotel, flight, job, etc.) whose items carry typed assets.",
            min_length=1,
        ),
    ] = None
    field_bindings: Annotated[
        list[catalog_field_binding.CatalogFieldBinding] | None,
        Field(
            description='Explicit mappings from format template slots to catalog item fields or typed asset pools. Optional — creative agents can infer mappings without them, but bindings make the relationship self-describing and enable validation. Covers scalar fields (asset_id → catalog_field), asset pools (asset_id → asset_group_id on the catalog item), and repeatable groups that iterate over catalog items.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var catalog_type : CatalogType
var feed_formats : list[FeedFormat] | None
var field_bindings : list[ScalarBinding | AssetPoolBinding | CatalogFieldBinding1] | None
var max_items : int | None
var min_items : int | None
var model_config
var offering_asset_constraints : list[OfferingAssetConstraint] | None
var required : bool | None
var required_fields : list[str] | None

Inherited members

class CatalogSelection (**data: Any)
Expand source code
class CatalogSelection(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    catalog_id: Annotated[
        str,
        Field(
            description='Seller-known catalog identifier returned by sync_catalogs.', min_length=1
        ),
    ]
    type: Annotated[
        catalog_type.CatalogType | None,
        Field(
            description="Catalog type. Structural types: 'offering' (AdCP Offering objects), 'product' (ecommerce entries), 'inventory' (stock per location), 'store' (physical locations), 'promotion' (deals and pricing). Vertical types: 'hotel', 'flight', 'job', 'vehicle', 'real_estate', 'education', 'destination', 'app' — each with an industry-specific item schema."
        ),
    ] = None
    ids: Annotated[
        list[str] | None,
        Field(
            description='Filter catalog to exact canonical item keys. The key field is offering_id for offering, store_id for store, hotel_id for hotel, flight_id for flight, job_id for job, vehicle_id for vehicle, listing_id for real_estate, program_id for education, destination_id for destination, and app_id for app. Product, inventory, and promotion catalogs use the stable normalized source identifier retained during ingestion (for example a retailer SKU). The same canonical key is used by catalog availability item_id.',
            min_length=1,
        ),
    ] = None
    gtins: Annotated[
        list[Gtin] | None,
        Field(
            description="Filter product-type catalogs by GTIN identifiers for cross-retailer catalog matching. Accepts standard GTIN formats (GTIN-8, UPC-A/GTIN-12, EAN-13/GTIN-13, GTIN-14). Only applicable when type is 'product'.",
            min_length=1,
        ),
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description='Filter catalog to items with these tags. Tags are matched using OR logic — items matching any tag are included.',
            min_length=1,
        ),
    ] = None
    category: Annotated[
        str | None,
        Field(
            description="Filter catalog to items in this category (e.g., 'beverages/soft-drinks', 'chef-positions')."
        ),
    ] = None
    query: Annotated[
        str | None,
        Field(
            description="Natural language filter for catalog items (e.g., 'all pasta sauces under $5', 'amsterdam vacancies').",
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var catalog_id : str
var category : str | None
var gtins : list[Gtin] | None
var ids : list[str] | None
var model_config
var query : str | None
var tags : list[str] | None
var type : CatalogType | None

Inherited members

class CatalogType (*args, **kwds)
Expand source code
class CatalogType(StrEnum):
    offering = 'offering'
    product = 'product'
    inventory = 'inventory'
    store = 'store'
    promotion = 'promotion'
    hotel = 'hotel'
    flight = 'flight'
    job = 'job'
    vehicle = 'vehicle'
    real_estate = 'real_estate'
    education = 'education'
    destination = 'destination'
    app = 'app'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var app
var destination
var education
var flight
var hotel
var inventory
var job
var offering
var product
var promotion
var real_estate
var store
var vehicle
class Catchment (**data: Any)
Expand source code
class Catchment(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catchment_id: Annotated[
        str,
        Field(
            description="Identifier for this catchment, used to reference specific catchment areas in targeting (e.g., 'walk', 'drive', 'primary')."
        ),
    ]
    label: Annotated[
        str | None,
        Field(
            description="Human-readable label for this catchment (e.g., '15-min drive', '1km walking radius')."
        ),
    ] = None
    travel_time: Annotated[
        TravelTime | None,
        Field(
            description='Travel time limit for isochrone calculation. The platform resolves this to a geographic boundary based on actual transportation networks, accounting for road connectivity, transit schedules, and terrain.'
        ),
    ] = None
    transport_mode: Annotated[
        transport_mode_1.TransportMode | None,
        Field(
            description='Transportation mode for isochrone calculation. Required when travel_time is provided.'
        ),
    ] = None
    radius: Annotated[
        Radius | None,
        Field(
            description="Simple radius from the store location. The platform draws a circle of this distance around the store's coordinates."
        ),
    ] = None
    geometry: Annotated[
        Geometry | None,
        Field(
            description='Pre-computed GeoJSON geometry defining the catchment boundary. Use this when the buyer has already calculated isochrones (via TravelTime, Mapbox, etc.) or has custom trade area boundaries. Supports Polygon and MultiPolygon types.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None

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

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 catchment_id : str
var ext : ExtensionObject | None
var geometry : Geometry | None
var label : str | None
var model_config
var radius : Radius | None
var transport_mode : TransportMode | None
var travel_time : TravelTime | None

Inherited members

class Category (*args, **kwds)
Expand source code
class Category(StrEnum):
    owned_property = 'owned_property'
    website = 'website'
    app = 'app'
    offline = 'offline'
    phone_call = 'phone_call'
    chat = 'chat'
    email = 'email'
    in_store = 'in_store'
    system_generated = 'system_generated'
    other = 'other'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var app
var chat
var email
var in_store
var offline
var other
var owned_property
var phone_call
var system_generated
var website
class ChangedFields (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class ChangedFields(RootModel[list[str]]):
    root: Annotated[
        list[str],
        Field(
            description='Advisory list of changed top-level field names from the source document. Example values for publisher.adagents_changed include "formats", "placements", and "authorized_agents"; for agent.profile_updated these are profile field names such as "channels" or "format_kinds". Producers SHOULD enumerate every changed semantic field, explicitly including formats and placements for catalog-only revisions (additive from 3.2). Consumers MAY use this for targeted index refresh but MUST re-resolve every depended-on field when reading an older retained event that lacks this list.',
            min_length=1,
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[list[str]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[str]
class Classification (*args, **kwds)
Expand source code
class Classification(StrEnum):
    property = 'property'
    ad_infra = 'ad_infra'
    publisher_mask = 'publisher_mask'
    network = 'network'
    unclassified = 'unclassified'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var ad_infra
var network
var property
var publisher_mask
var unclassified
class CloseReason (*args, **kwds)
Expand source code
class CloseReason(StrEnum):
    accepted_with_seller = 'accepted_with_seller'
    purchased_elsewhere = 'purchased_elsewhere'
    selected_alternative = 'selected_alternative'
    not_pursued = 'not_pursued'
    budget_changed = 'budget_changed'
    timing_changed = 'timing_changed'
    other = 'other'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var accepted_with_seller
var budget_changed
var not_pursued
var other
var purchased_elsewhere
var selected_alternative
var timing_changed
class Cloud (*args, **kwds)
Expand source code
class Cloud(StrEnum):
    aws = 'aws'
    azure = 'azure'
    gcp = 'gcp'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var aws
var azure
var gcp
class Collection (**data: Any)
Expand source code
class Collection(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Publisher namespace that owns this collection. Required for supply-path verification when the declaration is read from a cross-origin authoritative document; it must match the publisher whose origin delegated retrieval. A pointer alone cannot claim another publisher's collection. May be omitted for a publisher-origin document, where that origin supplies the namespace.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    collection_id: Annotated[
        str,
        Field(
            description="Publisher-assigned identifier for this collection. Declared in the publisher's adagents.json collections array. Products reference collections via collection selectors with publisher_domain and collection_ids. Use distribution identifiers for cross-seller matching across publishers."
        ),
    ]
    name: Annotated[str, Field(description='Human-readable collection name')]
    kind: Annotated[
        collection_kind.CollectionKind | None,
        Field(
            description="What kind of content program this is. Helps agents interpret installments correctly. A channel collection represents the persistent programmed stream; its installments, when present, are scheduled airings or programming blocks. Defaults to 'series' when absent."
        ),
    ] = None
    description: Annotated[str | None, Field(description='What the collection is about')] = None
    genre: Annotated[
        list[str] | None,
        Field(
            description='Genre tags. When genre_taxonomy is present, values are taxonomy IDs (e.g., IAB Content Taxonomy 3.0 codes). Otherwise free-form.'
        ),
    ] = None
    genre_taxonomy: Annotated[
        str | None,
        Field(
            description="Taxonomy system for genre values (e.g., 'iab_content_3.0'). When present, genre values should be valid taxonomy IDs. Recommended for machine-readable brand safety evaluation."
        ),
    ] = None
    language: Annotated[
        str | None, Field(description="Primary language (BCP 47 tag, e.g., 'en', 'es-MX')")
    ] = None
    content_rating: Annotated[
        content_rating_1.ContentRating | None,
        Field(
            description='Baseline content rating for the collection. Individual installments may override this.'
        ),
    ] = None
    cadence: Annotated[
        collection_cadence.CollectionCadence | None,
        Field(description='How frequently the collection releases new installments'),
    ] = None
    season: Annotated[
        str | None,
        Field(
            description="Current or most recent season identifier (e.g., '3', '2026', 'spring_2026'). A lightweight label — not a full season object."
        ),
    ] = None
    status: Annotated[
        collection_status.CollectionStatus | None,
        Field(description='Lifecycle status of the collection'),
    ] = None
    production_quality: Annotated[
        production_quality_1.ProductionQuality | None,
        Field(
            description='Production quality tier. Seller-declared. Maps to OpenRTB content.prodq (professional=1, prosumer=2, ugc=3).'
        ),
    ] = None
    talent: Annotated[
        list[talent_1.Talent] | None,
        Field(
            description='Hosts, recurring cast, creators associated with the collection. Each talent entry may include a brand_url linking to their brand.json identity.'
        ),
    ] = None
    special: Annotated[
        special_1.Special | None,
        Field(
            description='When present, this collection is a special — content anchored to a real-world event or occasion. Individual installments may override with their own event context.'
        ),
    ] = None
    limited_series: Annotated[
        limited_series_1.LimitedSeries | None,
        Field(
            description='When present, this collection is a limited series — a bounded run with a defined arc, installment count, and end date.'
        ),
    ] = None
    distribution: Annotated[
        list[collection_distribution.CollectionDistribution] | None,
        Field(
            description="Where this collection is distributed. Each entry maps the collection to a publisher platform using host property IDs, identifiers, or both. For channel collections this is the carriage map. It is a publisher assertion for discovery, not sales authorization; buyers validate owner-sold carriage against the host publisher's collection-scoped authorized_agents declaration. Collections SHOULD include at least one platform-independent identifier (imdb_id, gracenote_id, eidr_id) when available."
        ),
    ] = None
    deadline_policy: Annotated[
        deadline_policy_1.DeadlinePolicy | None,
        Field(
            description="Default deadline rules for installments of this collection. Agents compute absolute deadlines from each installment's scheduled_at and these lead times. Installments with explicit deadlines override this policy. Only meaningful when installments carry scheduled_at; a continuously programmed channel collection without enumerated installments has no deadlines to derive."
        ),
    ] = None
    related_collections: Annotated[
        list[RelatedCollection] | None,
        Field(
            description="Relationships to other collections (spin-offs, companion collections, etc.). Each entry references another collection by collection_id within the same publisher's adagents.json."
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 cadence : CollectionCadence | None
var collection_id : str
var content_rating : ContentRating | None
var deadline_policy : DeadlinePolicy | None
var description : str | None
var distribution : list[CollectionDistribution] | None
var ext : ExtensionObject | None
var genre : list[str] | None
var genre_taxonomy : str | None
var kind : CollectionKind | None
var language : str | None
var limited_series : LimitedSeries | None
var model_config
var name : str
var production_quality : ProductionQuality | None
var publisher_domain : str | None
var related_collections : list[RelatedCollection] | None
var season : str | None
var special : Special | None
var status : CollectionStatus | None
var talent : list[Talent] | None

Inherited members

class CollectionDeliveryMetrics (**data: Any)
Expand source code
class CollectionDeliveryMetrics(DeliveryMetrics):
    collection_ref: collection_ref_1.CollectionReference
    collection_name: Annotated[
        str | None,
        Field(
            description='Current human-readable collection name. Convenience metadata only; collection_ref is stable identity.'
        ),
    ] = None
    impressions: Any
    spend: Any

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 collection_name : str | None
var collection_ref : CollectionReference
var impressions : Any
var model_config
var spend : Any

Inherited members

class CollectionDistribution (**data: Any)
Expand source code
class CollectionDistribution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description="Domain of the publisher platform where the collection is distributed (e.g., 'youtube.com', 'spotify.com'). Property IDs and publisher-scoped identifiers in this object resolve in this publisher's namespace."
        ),
    ]
    property_ids: Annotated[
        list[property_id.PropertyId] | None,
        Field(
            description="Publisher-scoped property IDs from publisher_domain's adagents.json that carry this collection. For owner-sold channel inventory, these identify the host apps without requiring the host to publish channel-owner placement definitions.",
            min_length=1,
        ),
    ] = None
    identifiers: Annotated[
        list[Identifier] | None,
        Field(
            description='Identifiers for the collection on this publisher, including publisher-scoped channel/EPG identifiers and platform-independent metadata identifiers',
            min_length=1,
        ),
    ] = None

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

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 identifiers : list[Identifier] | None
var model_config
var property_ids : list[PropertyId] | None
var publisher_domain : str

Inherited members

class CollectionIdentifier (**data: Any)
Expand source code
class CollectionIdentifier(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    publisher_domain: Annotated[
        Domain,
        Field(description='Distribution platform domain, such as youtube.com or spotify.com.'),
    ]
    type: distribution_identifier_type.DistributionIdentifierType
    value: str

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var publisher_domain : Domain
var type : DistributionIdentifierType
var value : str

Inherited members

class CollectionListReference (**data: Any)
Expand source code
class CollectionListReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[AnyUrl, Field(description='URL of the agent managing the collection list')]
    list_id: Annotated[
        str, Field(description='Identifier for the collection list within the agent', min_length=1)
    ]
    auth_token: Annotated[
        str | None,
        Field(
            description='JWT or other authorization token for accessing the list. Optional if the list is public or caller has implicit access.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var auth_token : str | None
var list_id : str
var model_config

Inherited members

class CollectionPayload (**data: Any)
Expand source code
class CollectionPayload(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    collection_rid: UUID | None = None
    publisher_domain: Domain | None = None
    collection_id: Annotated[
        str | None,
        Field(description='Publisher-local collection_id from the authoritative adagents.json.'),
    ] = None
    name: str | None = None
    kind: collection_kind.CollectionKind | None = None
    source: PropertySource | None = None
    status: Status | None = None
    identifiers: Annotated[
        list[CollectionIdentifier] | None,
        Field(description='Distribution identifiers that alias this collection across platforms.'),
    ] = None
    collection: Annotated[
        collection_1.Collection | None,
        Field(description='Optional full post-change collection object when available.'),
    ] = None
    changed_fields: ChangedFields | 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

Subclasses

Class variables

var changed_fields : ChangedFields | None
var collection : Collection | None
var collection_id : str | None
var collection_rid : uuid.UUID | None
var identifiers : list[CollectionIdentifier] | None
var kind : CollectionKind | None
var model_config
var name : str | None
var publisher_domain : Domain | None
var source : PropertySource | None
var status : Status | None

Inherited members

class CollectionPropertyDeliveryMetrics (**data: Any)
Expand source code
class CollectionPropertyDeliveryMetrics(DeliveryMetrics):
    collection_ref: collection_ref_1.CollectionReference
    collection_name: Annotated[
        str | None,
        Field(description='Current human-readable collection name. Convenience metadata only.'),
    ] = None
    publisher_domain: Annotated[
        str,
        Field(
            description='Publisher or platform authority that namespaces the property identifier, including for an unregistered surface.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    identifier: Annotated[
        identifier_1.Identifier,
        Field(description='Operational identity of the property that delivered.'),
    ]
    property_ref: Annotated[
        property_ref_1.PropertyReference | None,
        Field(
            description="Canonical publisher-scoped catalog identity when available. Its publisher_domain MUST equal the row's publisher_domain."
        ),
    ] = None
    property_name: Annotated[
        str | None,
        Field(description='Current human-readable property name. Convenience metadata only.'),
    ] = None
    impressions: Any
    spend: Any

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 collection_name : str | None
var collection_ref : CollectionReference
var identifier : Identifier
var impressions : Any
var model_config
var property_name : str | None
var property_ref : PropertyReference | None
var publisher_domain : str
var spend : Any

Inherited members

class CollectionReference (**data: Any)
Expand source code
class CollectionReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description='Domain where the adagents.json declaring this collection is hosted.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    collection_id: Annotated[
        str,
        Field(
            description="Collection ID from the publisher's adagents.json collection catalog.",
            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 collection_id : str
var model_config
var publisher_domain : str

Inherited members

class CollectionSelection1 (**data: Any)
Expand source code
class CollectionSelection1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['selected'] = 'selected'
    collections: Annotated[
        list[collection_selector.CollectionSelector],
        Field(
            description="Complete required collection set as domain-qualified selectors with explicit collection_ids; the domain-only bulk-grant form is authorization scoping, not selection. publisher_domain may be an external channel owner's domain.",
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 collections : list[CollectionSelector]
var ext : ExtensionObject | None
var mode : Literal['selected']
var model_config

Inherited members

class CollectionSelection2 (**data: Any)
Expand source code
class CollectionSelection2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['default'] = 'default'
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var mode : Literal['default']
var model_config

Inherited members

class CollectionSelector (**data: Any)
Expand source code
class CollectionSelector(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description="Domain where the adagents.json declaring these collections is hosted (e.g., 'mrbeast.com'). The collections array in that file contains the authoritative collection definitions.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    collection_ids: Annotated[
        list[str] | None,
        Field(
            description='Collection IDs from the adagents.json collections array. Each ID must match a collection_id declared in that file. Omit to reference all collections declared in that file.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var collection_ids : list[str] | None
var model_config
var publisher_domain : str

Inherited members

class Color (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class Color(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^#[0-9A-Fa-f]{6}$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class Colors (**data: Any)
Expand source code
class Colors(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    primary: Annotated[str | None, Field(pattern='^#[0-9a-fA-F]{6}$')] = None
    secondary: Annotated[str | None, Field(pattern='^#[0-9a-fA-F]{6}$')] = None
    accent: Annotated[str | None, Field(pattern='^#[0-9a-fA-F]{6}$')] = 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 accent : str | None
var model_config
var primary : str | None
var secondary : str | None

Inherited members

class CommittedMetric1 (**data: Any)
Expand source code
class CommittedMetric1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Annotated[
        Literal['standard'],
        Field(description='Standard metric from the closed `available-metric.json` enum.'),
    ] = 'standard'
    metric_id: Annotated[
        available_metric.AvailableMetric, Field(description='Identifier for the standard metric.')
    ]
    qualifier: Annotated[
        QualifierModel | None,
        Field(
            description="Disambiguates metrics whose definition varies by qualifier. Today carries five keys — `viewability_standard` (MRC vs GroupM viewability), `completion_source` (seller- vs vendor-attested completion), `attribution_methodology` (how attribution was computed for outcome metrics), `attribution_window` (the time window over which outcomes were attributed), and `lift_dimension` (which dimension of brand_lift this row represents — awareness, consideration, etc.). Required when the underlying `metric_id` has multiple incompatible measurement paths AND the seller commits to a specific one. Symmetric on `missing_metrics`. Reserved for additive qualifiers in future minors — schema is closed (`additionalProperties: false`); new keys ship explicitly. **Heterogeneous value types**: qualifier values can be either string enums (`viewability_standard`, `completion_source`, `attribution_methodology`, `lift_dimension`) or structured objects (`attribution_window` is a duration `{interval, unit}`). Consumers MUST dispatch on key name to know value shape; structured-value qualifiers join on canonical (key-sorted) deep equality so `{interval: 14, unit: 'days'}` and `{unit: 'days', interval: 14}` resolve to the same partition. Rate-style metrics (`new_to_brand_rate`, `engagement_rate`, etc.) inherit the methodology of their numerator — when a rate carries `attribution_methodology` qualifier, it applies to the underlying conversions/events being rated."
        ),
    ] = None
    committed_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when this metric became part of the contract. Day-1 commitments use `create_media_buy.confirmed_at`; mid-flight additions use the time the amendment was 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

Class variables

var committed_at : pydantic.types.AwareDatetime
var metric_id : AvailableMetric
var model_config
var qualifier : QualifierModel | None
var scope : Literal['standard']

Inherited members

class CommittedMetric2 (**data: Any)
Expand source code
class CommittedMetric2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Annotated[
        Literal['vendor'],
        Field(description='Vendor-defined metric, identified by the tuple `(vendor, metric_id)`.'),
    ] = 'vendor'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description="Vendor that defines and computes this metric. The vendor's `brand.json` `agents[type='measurement']` is the canonical anchor."
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(description="Identifier for the metric within the vendor's vocabulary."),
    ]
    methodology_version: Annotated[
        str | None,
        Field(
            description="Optional pin of the vendor's `get_adcp_capabilities.measurement.metrics[].methodology_version` that this commitment is contracted against. When present, the seller commits to reporting values computed under this methodology version; a vendor-side methodology change that alters the value definition is a contract change and SHOULD surface as a new appended entry with its own `committed_at`, never a silent substitution. Absence means the contract does not pin a version and buyers MUST treat methodology changes as untracked. Opaque string — compare for equality, do not parse."
        ),
    ] = None
    qualifier: Annotated[
        Qualifier1 | None,
        Field(
            description='Optional qualifier disambiguating commitments to the same vendor metric measured under different methodologies or windows. Same closed key set as standard-scope entries; new keys ship explicitly.'
        ),
    ] = None
    committed_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when this vendor metric became part of the contract.'
        ),
    ]

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 committed_at : pydantic.types.AwareDatetime
var methodology_version : str | None
var metric_id : VendorMetricId
var model_config
var qualifier : Qualifier1 | None
var scope : Literal['vendor']
var vendor : BrandReference

Inherited members

class CompactTaskInputRequired (**data: Any)
Expand source code
class CompactTaskInputRequired(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    reason: Annotated[str | None, Field(max_length=200, min_length=1)] = None
    message: Annotated[str | None, Field(max_length=2000)] = None
    errors: list[error.Error] | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

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

Inherited members

class CompactTaskSubmitted (**data: Any)
Expand source code
class CompactTaskSubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Literal['submitted'] = 'submitted'
    task_id: Annotated[str, Field(min_length=1)]
    message: Annotated[str | None, Field(max_length=2000)] = None
    errors: list[error.Error] | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

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

Inherited members

class CompactTaskWorking (**data: Any)
Expand source code
class CompactTaskWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[StrictFloat | None, Field(ge=0.0, le=100.0)] = None
    current_step: Annotated[str | None, Field(max_length=500)] = None
    total_steps: Annotated[SchemaInt | None, Field(ge=1)] = None
    step_number: Annotated[SchemaInt | None, Field(ge=1)] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var context : ContextObject | None
var current_step : str | None
var ext : ExtensionObject | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class CompliancePayload (**data: Any)
Expand source code
class CompliancePayload(Payload7):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class ComplianceStatus (*args, **kwds)
Expand source code
class ComplianceStatus(StrEnum):
    passing = 'passing'
    degraded = 'degraded'
    failing = 'failing'
    unknown = 'unknown'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var degraded
var failing
var passing
var unknown
class Compression (*args, **kwds)
Expand source code
class Compression(StrEnum):
    gzip = 'gzip'
    none = 'none'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var gzip
var none
class Condition (*args, **kwds)
Expand source code
class Condition(StrEnum):
    new = 'new'
    used = 'used'
    certified_pre_owned = 'certified_pre_owned'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var certified_pre_owned
var new
var used
class ConfidenceInterval (**data: Any)
Expand source code
class ConfidenceInterval(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    lower: StrictFloat
    upper: StrictFloat
    level: Annotated[StrictFloat, Field(gt=0.0, lt=1.0)]

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 level : float
var lower : float
var model_config
var upper : float

Inherited members

class Connection (**data: Any)
Expand source code
class Connection(DownstreamConnectionRequirement):
    status: Annotated[
        Literal['unknown'],
        Field(
            description='Current seller-observed state for this downstream connection when known. Product declarations MAY omit status or use `unknown`; AUTHORIZATION_REQUIRED details SHOULD use `missing`, `expired`, or `revoked` for the connection that blocked the call.'
        ),
    ] = 'unknown'
    required_for: Annotated[
        list[RequiredForItem] | None,
        Field(
            description='Concrete AdCP protocol operation names that require this downstream connection. Sellers SHOULD include this in product declarations when the requirement is known ahead of time, and in AUTHORIZATION_REQUIRED details when it explains the failed operation. Prefer specific operation names such as `list_creatives`, `sync_creatives`, `create_media_buy`, `get_media_buy_delivery`, or `get_creative_delivery` over broad category labels such as `reporting`.'
        ),
    ] = 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 model_config
var required_for : list[RequiredForItem] | None
var status : Literal['unknown']

Inherited members

class ConnectionType (*args, **kwds)
Expand source code
class ConnectionType(StrEnum):
    advertiser_account = 'advertiser_account'
    publisher_identity = 'publisher_identity'
    post_authorization = 'post_authorization'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var advertiser_account
var post_authorization
var publisher_identity
class Constraint (*args, **kwds)
Expand source code
class Constraint(StrEnum):
    safe_area = 'safe_area'
    reserved_region = 'reserved_region'
    decoration_only_edge = 'decoration_only_edge'
    no_text_or_logos = 'no_text_or_logos'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var decoration_only_edge
var no_text_or_logos
var reserved_region
var safe_area
class ConsumerIdentity (**data: Any)
Expand source code
class ConsumerIdentity(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    cloud: Annotated[
        Cloud | None, Field(description="Cloud family hosting this identity's account.")
    ] = None
    region: Annotated[
        str | None,
        Field(
            description="Vendor/cloud region identifier. Format follows the cloud family's region naming; not constrained by this schema."
        ),
    ] = None
    identity: Annotated[
        str,
        Field(
            description="Principal to grant, interpreted relative to the enclosing entry's vendor.domain. Format is vendor-specific and opaque — Snowflake: orgname.accountname; Databricks: sharing recipient identifier; BigQuery: IAM principal.",
            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 cloud : Cloud | None
var identity : str
var model_config
var region : str | None

Inherited members

class ConsumerStatus (*args, **kwds)
Expand source code
class ConsumerStatus(StrEnum):
    received = 'received'
    obligation_missing = 'obligation_missing'
    revision_missing = 'revision_missing'
    unreadable = 'unreadable'
    content_mismatch = 'content_mismatch'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var content_mismatch
var obligation_missing
var received
var revision_missing
var unreadable
class Contact (**data: Any)
Expand source code
class Contact(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    role: Annotated[
        Role, Field(description="Contact's functional role in the business relationship")
    ]
    name: Annotated[str | None, Field(description='Full name of the contact', max_length=200)] = (
        None
    )
    email: Annotated[EmailStr | None, Field(max_length=254)] = None
    phone: Annotated[str | None, Field(max_length=30)] = 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 email : pydantic.networks.EmailStr | None
var model_config
var name : str | None
var phone : str | None
var role : Role

Inherited members

class Content (**data: Any)
Expand source code
class Content(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    id: Annotated[str, Field(description='Product or content identifier')]
    quantity: Annotated[SchemaInt | None, Field(description='Quantity of this item', ge=1)] = None
    price: Annotated[
        StrictFloat | None, Field(description='Price per unit of this item', ge=0.0)
    ] = None
    brand: Annotated[str | None, Field(description='Brand name of this item')] = 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 brand : str | None
var id : str
var model_config
var price : float | None
var quantity : int | None

Inherited members

class ContentIdType (*args, **kwds)
Expand source code
class ContentIdType(StrEnum):
    sku = 'sku'
    gtin = 'gtin'
    offering_id = 'offering_id'
    job_id = 'job_id'
    hotel_id = 'hotel_id'
    flight_id = 'flight_id'
    vehicle_id = 'vehicle_id'
    listing_id = 'listing_id'
    store_id = 'store_id'
    program_id = 'program_id'
    destination_id = 'destination_id'
    app_id = 'app_id'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var app_id
var destination_id
var flight_id
var gtin
var hotel_id
var job_id
var listing_id
var offering_id
var program_id
var sku
var store_id
var vehicle_id
class ContentRating (**data: Any)
Expand source code
class ContentRating(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    system: Annotated[
        content_rating_system.ContentRatingSystem, Field(description='Rating system used')
    ]
    rating: Annotated[
        str, Field(description="Rating value within the system (e.g., 'TV-PG', 'R', 'explicit')")
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var rating : str
var system : ContentRatingSystem

Inherited members

class ContextObject (**data: Any)
Expand source code
class ContextObject(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class ContractVersion (*args, **kwds)
Expand source code
class ContractVersion(StrEnum):
    field_1_0 = '1.0'
    field_1_1 = '1.1'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var field_1_0
var field_1_1
class ControlMediaBuyInputRequired (**data: Any)
Expand source code
class ControlMediaBuyInputRequired(CompactTaskInputRequired):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class ControlMediaBuySubmitted (**data: Any)
Expand source code
class ControlMediaBuySubmitted(CompactTaskSubmitted):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class ControlMediaBuyWorking (**data: Any)
Expand source code
class ControlMediaBuyWorking(CompactTaskWorking):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class ConversionTracking (**data: Any)
Expand source code
class ConversionTracking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    action_sources: Annotated[
        list[action_source.ActionSource] | None,
        Field(
            description="Action sources relevant to this product (e.g. a retail media product might have 'in_store' and 'website', while a display product might only have 'website')",
            min_length=1,
        ),
    ] = None
    supported_targets: Annotated[
        list[SupportedTarget5] | None,
        Field(
            description='Target kinds available for event goals on this product. Values match target.kind on the optimization goal. cost_per: target cost per conversion event. per_ad_spend: target return on ad spend (requires value_field on event sources). maximize_value: maximize total conversion value without a specific ratio target (requires value_field). Only these target kinds are accepted — goals with unlisted target kinds will be rejected. A goal without a target implicitly maximizes conversion count within budget — no declaration needed for that mode. When omitted, buyers can still set target-less event goals.',
            min_length=1,
        ),
    ] = None
    platform_managed: Annotated[
        StrictBool | None,
        Field(
            description="Whether the seller provides its own always-on measurement (e.g. Amazon sales attribution for Amazon advertisers). When true, sync_event_sources response will include seller-managed event sources with managed_by='seller'."
        ),
    ] = 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 action_sources : list[ActionSource] | None
var model_config
var platform_managed : bool | None
var supported_targets : list[SupportedTarget5] | None

Inherited members

class CostPer (**data: Any)
Expand source code
class CostPer(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    amount: Annotated[
        StrictFloat,
        Field(
            description='Average cost amount per scope-bound primary-goal result, denominated in the media-buy currency.',
            gt=0.0,
        ),
    ]
    strength: Annotated[
        Strength,
        Field(
            description='`cap` optimizes for an average at or below the amount and accepts underdelivery when necessary; `target` optimizes around the amount while balancing volume and spend. Neither is a per-result or per-auction guarantee.'
        ),
    ]

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 amount : float
var model_config
var strength : Strength

Inherited members

class CostPerStrength (*args, **kwds)
Expand source code
class CostPerStrength(StrEnum):
    cap = 'cap'
    target = 'target'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var cap
var target
class Countries1 (**data: Any)
Expand source code
class Countries1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[Value],
        Field(
            description='Exact finite set of ISO 3166-2 identifiers the buyer may select later.',
            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 model_config
var values : list[Value]

Inherited members

class Countries3 (**data: Any)
Expand source code
class Countries3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[Value],
        Field(
            description='Exact finite selectable subset of ISO 3166-2 identifiers for this country.',
            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 model_config
var values : list[Value]

Inherited members

class CountrySupport (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class CountrySupport(RootModel[Supported | CountrySupport1]):
    root: Supported | CountrySupport1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Union[Supported, CountrySupport1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Supported | CountrySupport1
class CountrySupport1 (**data: Any)
Expand source code
class CountrySupport1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    max_values_per_package: Annotated[
        SchemaInt,
        Field(
            description='Maximum number of country values accepted in this targeting field on one package.',
            ge=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var max_values_per_package : int
var model_config

Inherited members

class CoverageRequirement (*args, **kwds)
Expand source code
class CoverageRequirement(StrEnum):
    full = 'full'
    allow_partial = 'allow_partial'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var allow_partial
var full
class CreateMediaBuyInputRequired (**data: Any)
Expand source code
class CreateMediaBuyInputRequired(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    reason: Annotated[
        Reason | None, Field(description='Reason code indicating why input is needed')
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional validation errors or warnings for debugging purposes. Helps explain why input is required.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var model_config
var reason : Reason | None

Inherited members

class CreateMediaBuySubmitted (**data: Any)
Expand source code
class CreateMediaBuySubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal. Discriminates this async envelope from the synchronous success shape, which carries media-buy lifecycle state in `media_buy_status`. See task-status.json for the full task-status enum.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='Task handle the buyer uses with get_task_status (or the legacy AdCP tasks/get alias), and that the seller references on push-notification callbacks. The media_buy_id is issued on the completion artifact, not here. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A Task id.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description="Optional human-readable explanation of why the task is submitted — e.g., 'Awaiting IO signature from sales team; typical turnaround 2–4 hours.' Plain text only. Buyers MUST treat this as untrusted seller input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile seller may inject prompt-injection payloads aimed at the buyer's agent.",
            max_length=2000,
        ),
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories, governance observations). Terminal failures belong in the error branch, not here.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class CreateMediaBuyWorking (**data: Any)
Expand source code
class CreateMediaBuyWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0)
    ] = None
    current_step: Annotated[
        str | None, Field(description='Current step or phase of the operation')
    ] = None
    total_steps: Annotated[
        SchemaInt | None, Field(description='Total number of steps in the operation', ge=1)
    ] = None
    step_number: Annotated[SchemaInt | None, Field(description='Current step number', ge=1)] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var current_step : str | None
var ext : ExtensionObject | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class CreativeAsset (**data: Any)
Expand source code
class CreativeAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    creative_id: Annotated[
        str,
        Field(
            description='Unique identifier for the creative. Stable across legacy named-format and 3.1+ canonical-format paths — a creative registered against `format_id` retains the same `creative_id` when later viewed through a canonical-format flatten.'
        ),
    ]
    name: Annotated[str, Field(description='Human-readable creative name')]
    format_id: Annotated[
        format_id_1.FormatReferenceStructuredObject | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format path retained for older 3.x peers. New creative assets use `format_kind` and optional `format_option_ref`.',
        ),
    ] = None
    format_kind: Annotated[
        str | None,
        Field(
            description='Canonical format name this creative targets (e.g., `image`, `video_hosted`). Mutually exclusive with deprecated `format_id`.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='3.1+ format-option path, optional. Structured format option reference matching one of the target product\'s `format_options[]` declarations. Publisher-catalog-backed options match by `{ scope: "publisher", publisher_domain, format_option_id }`; product-local options match by `{ scope: "product", format_option_id }`. Required when the target product has multiple `format_options` entries sharing the same `format_kind`; optional when `format_kind` alone routes the creative to a single declaration. Product-scoped refs require an enclosing target product/package context.'
        ),
    ] = None
    representation_selection: Annotated[
        representation_selection_1.RepresentationSelection | None,
        Field(
            description='Readback lineage to the complete CreativeRepresentationSet revision and representation selected before this seller-bound creative was synced.'
        ),
    ] = None
    assets: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')], asset_union.AssetVariant | Assets],
        Field(
            description='Assets required by the format, keyed by asset_id or canonical asset_group_id. Each slot value is either a single asset object or an array of asset objects (for slots with `min`/`max > 1` like carousel `cards` or responsive_creative `headlines`). Each asset value carries an `asset_type` discriminator that selects the matching asset schema, including reference assets such as `published_post` when a product accepts already-published post references.'
        ),
    ]
    component_assets: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[a-z][a-z0-9_]*$')], creative_assets.CreativeAssets] | None,
        Field(
            description='Component-addressed canonical asset maps for `coordinated_placements`. Keys match coordinated component IDs. This field is preserved by creative-library sync and list readback; it MUST be absent for every other format kind.'
        ),
    ] = None
    inputs: Annotated[
        list[Input] | None,
        Field(
            description='Preview contexts for generative formats - defines what scenarios to generate previews for'
        ),
    ] = None
    tags: Annotated[
        list[str] | None, Field(description='User-defined tags for organization and searchability')
    ] = None
    status: Annotated[
        creative_status.CreativeStatus | None,
        Field(
            description="For generative creatives: set to 'approved' to finalize, 'rejected' to request regeneration with updated assets/message. Omit for non-generative creatives (system will set based on processing state)."
        ),
    ] = None
    weight: Annotated[
        StrictFloat | None,
        Field(
            description='Optional delivery weight for creative rotation when uploading via create_media_buy or update_media_buy (0-100). If omitted, platform determines rotation. Only used during upload to media buy - not stored in creative library.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description="Optional structured product-context placement references where this uploaded creative should run when uploading via create_media_buy or update_media_buy. These items always use placement-ref product-context semantics, even when tolerated additional members make an item resemble placement-identity. Receivers match only against the target package's committed placement set; kind and seller_agent are non-authoritative for routing and MUST NOT expand or reinterpret that set. A receiver MUST reject a ref when the enclosing product and committed set do not yield one unambiguous match. New senders SHOULD include publisher_domain for publisher-catalog placements. If omitted, creative runs on all buyer-targetable placements. If both `placement_refs` and legacy `placement_ids` are present, `placement_refs` wins and receivers MUST ignore `placement_ids`. Only used during upload to media buy - not stored in creative library.",
            min_length=1,
        ),
    ] = None
    placement_ids: Annotated[
        list[str] | None,
        Field(
            deprecated=True,
            description='Legacy shorthand array of placement IDs where this creative should run when uploading via create_media_buy or update_media_buy. New senders SHOULD use `placement_refs` because placement IDs are publisher-scoped and strings are ambiguous in multi-publisher products. If omitted, creative runs on all buyer-targetable placements. If `placement_refs` is also present, receivers MUST ignore this field. Only used during upload to media buy - not stored in creative library.',
            min_length=1,
        ),
    ] = None
    industry_identifiers: Annotated[
        list[industry_identifier.IndustryIdentifier] | None,
        Field(
            description='Industry-standard or market-specific identifiers for this creative (e.g., Ad-ID, ISCI, Clearcast clock number, IDcrea). In broadcast and scheduled audio/video buying, these identifiers tie the creative to rotation instructions, clearance records, and traffic systems. A creative may have multiple identifiers when different systems reference the same asset. Add a PR to extend creative-identifier-type when another shared identifier scheme needs first-class support.'
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this creative. Serves as the default provenance for all manifests and assets within this creative. A manifest or asset with its own provenance replaces this object entirely (no field-level merging).'
        ),
    ] = None
    rights: Annotated[
        list[rights_constraint.RightsConstraint] | None,
        Field(
            description='Rights constraints that MUST survive sync, package assignment, and list readback. Buyer-carried constraints and references do not authorize serving; the seller evaluates them under media_buy.rights_attestations and its adcp.attestations policy.',
            min_length=1,
        ),
    ] = None

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

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 assets : dict[str, ImageAsset | VideoAsset | AudioAsset | VastAsset | DisplayTagAsset | TextAsset | UrlAsset | HtmlAsset | JavascriptAsset | ZipAsset | WebhookAsset | CssAsset | DaastAsset | MarkdownAsset | BriefAsset | CatalogAsset | PublishedPostAsset | CardAsset | PixelTrackerAsset | VastTrackerAsset | DaastTrackerAsset | Assets]
var component_assets : dict[str, CreativeAssets] | None
var creative_id : str
var format_id : FormatReferenceStructuredObject | None
var format_kind : str | None
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var industry_identifiers : list[IndustryIdentifier] | None
var inputs : list[Input] | None
var model_config
var name : str
var placement_ids : list[str] | None
var placement_refs : list[PlacementReference] | None
var provenance : Provenance | None
var representation_selection : RepresentationSelection | None
var rights : list[RightsConstraint] | None
var status : CreativeStatus | None
var tags : list[str] | None
var weight : float | None

Inherited members

class CreativeAssets (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class CreativeAssets(
    RootModel[dict[Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')], asset_union.AssetVariant | CreativeAssets1]]
):
    root: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')], asset_union.AssetVariant | CreativeAssets1],
        Field(
            description='Map of canonical asset-group or legacy asset identifiers to supplied creative assets. Values are either a single discriminated asset or a non-empty repeatable asset array.',
            title='Creative Assets',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[dict[Annotated[str, StringConstraints], Union[Annotated[Union[ImageAsset, VideoAsset, AudioAsset, VastAsset, DisplayTagAsset, TextAsset, UrlAsset, HtmlAsset, JavascriptAsset, ZipAsset, WebhookAsset, CssAsset, DaastAsset, MarkdownAsset, BriefAsset, CatalogAsset, PublishedPostAsset, CardAsset, PixelTrackerAsset, VastTrackerAsset, DaastTrackerAsset], FieldInfo(annotation=NoneType, required=True, title='AssetVariant', description='Canonical union of all asset variant schemas. Referenced from creative-asset.json and creative-manifest.json to ensure a single named type is emitted by schema-to-TypeScript tooling. Add new asset types here and to the creative/asset-types registry.', discriminator='asset_type')], CreativeAssets1]]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : dict[str, ImageAsset | VideoAsset | AudioAsset | VastAsset | DisplayTagAsset | TextAsset | UrlAsset | HtmlAsset | JavascriptAsset | ZipAsset | WebhookAsset | CssAsset | DaastAsset | MarkdownAsset | BriefAsset | CatalogAsset | PublishedPostAsset | CardAsset | PixelTrackerAsset | VastTrackerAsset | DaastTrackerAsset | CreativeAssets1]
class CreativeAssets1 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class CreativeAssets1(RootModel[list[asset_union.AssetVariant]]):
    root: Annotated[list[asset_union.AssetVariant], Field(min_length=1)]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[list[Annotated[Union[ImageAsset, VideoAsset, AudioAsset, VastAsset, DisplayTagAsset, TextAsset, UrlAsset, HtmlAsset, JavascriptAsset, ZipAsset, WebhookAsset, CssAsset, DaastAsset, MarkdownAsset, BriefAsset, CatalogAsset, PublishedPostAsset, CardAsset, PixelTrackerAsset, VastTrackerAsset, DaastTrackerAsset], FieldInfo(annotation=NoneType, required=True, title='AssetVariant', description='Canonical union of all asset variant schemas. Referenced from creative-asset.json and creative-manifest.json to ensure a single named type is emitted by schema-to-TypeScript tooling. Add new asset types here and to the creative/asset-types registry.', discriminator='asset_type')]]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

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

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

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

Inherited members

class CreativeConsumption (**data: Any)
Expand source code
class CreativeConsumption(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    tokens: Annotated[
        SchemaInt | None,
        Field(description='LLM or generation tokens consumed during creative generation.', ge=0),
    ] = None
    images_generated: Annotated[
        SchemaInt | None, Field(description='Number of images produced during generation.', ge=0)
    ] = None
    renders: Annotated[
        SchemaInt | None,
        Field(description='Number of render passes performed (video, animation).', ge=0),
    ] = None
    duration_seconds: Annotated[
        StrictFloat | None,
        Field(
            description='Processing time billed, in seconds. For compute-time pricing models.',
            ge=0.0,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var duration_seconds : float | None
var images_generated : int | None
var model_config
var renders : int | None
var tokens : int | None

Inherited members

class CreativeDeliveryMetrics (**data: Any)
Expand source code
class CreativeDeliveryMetrics(DeliveryMetrics):
    creative_id: Annotated[
        str, Field(description='Creative identifier matching the creative assignment')
    ]
    creative_name: Annotated[
        str | None,
        Field(
            description='Optional human-readable creative name current when the report is generated. Convenience metadata only: names may change and buyers MUST use creative_id as the stable identity.'
        ),
    ] = None
    weight: Annotated[
        StrictFloat | None,
        Field(
            description='Observed delivery share for this creative within the package during the reporting period, expressed as a percentage (0-100). Reflects actual delivery distribution, not a configured setting.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    impressions: Any
    spend: Any

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var creative_id : str
var creative_name : str | None
var impressions : Any
var model_config
var spend : Any
var weight : float | None

Inherited members

class CreativeFilters (**data: Any)
Expand source code
class CreativeFilters(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    accounts: Annotated[
        list[account_ref.AccountReference] | None,
        Field(
            description='Filter creatives by owning accounts. Useful for agencies managing multiple client accounts.',
            min_length=1,
        ),
    ] = None
    statuses: Annotated[
        list[creative_status.CreativeStatus] | None,
        Field(description='Filter by creative approval statuses', min_length=1),
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(description='Filter by creative tags (all tags must match)', min_length=1),
    ] = None
    tags_any: Annotated[
        list[str] | None,
        Field(description='Filter by creative tags (any tag must match)', min_length=1),
    ] = None
    name_contains: Annotated[
        str | None,
        Field(description='Filter by creative names containing this text (case-insensitive)'),
    ] = None
    creative_ids: Annotated[
        list[str] | None,
        Field(description='Filter by specific creative IDs', max_length=100, min_length=1),
    ] = None
    created_after: Annotated[
        AwareDatetime | None,
        Field(description='Filter creatives created after this date (ISO 8601)'),
    ] = None
    created_before: Annotated[
        AwareDatetime | None,
        Field(description='Filter creatives created before this date (ISO 8601)'),
    ] = None
    updated_after: Annotated[
        AwareDatetime | None,
        Field(description='Filter creatives last updated after this date (ISO 8601)'),
    ] = None
    updated_before: Annotated[
        AwareDatetime | None,
        Field(description='Filter creatives last updated before this date (ISO 8601)'),
    ] = None
    assigned_to_packages: Annotated[
        list[str] | None,
        Field(
            description='Filter creatives assigned to any of these packages. Sales-agent-specific — standalone creative agents SHOULD ignore this filter.',
            min_length=1,
        ),
    ] = None
    media_buy_ids: Annotated[
        list[str] | None,
        Field(
            description='Filter creatives assigned to any of these media buys. Sales-agent-specific — standalone creative agents SHOULD ignore this filter.',
            min_length=1,
        ),
    ] = None
    unassigned: Annotated[
        StrictBool | None,
        Field(
            description='Filter for unassigned creatives when true, assigned creatives when false. Sales-agent-specific — standalone creative agents SHOULD ignore this filter.'
        ),
    ] = None
    has_served: Annotated[
        StrictBool | None,
        Field(
            description='When true, return only creatives that have served at least one impression. When false, return only creatives that have never served.'
        ),
    ] = None
    indicator_types: Annotated[
        list[indicator_type.IndicatorType] | None,
        Field(
            description='Return creatives with at least one package assignment carrying any requested current indicator type. Values within this field use OR logic; this field composes with other filters using AND logic. Sales-agent-specific: sellers support this filter only when media_buy.relationship_notifications.projection_tasks includes list_creatives. Other agents SHOULD ignore it and apply remaining filters. Buyers needing exact results MUST verify capability support and paginate the outer result set; assignment_projection: matching bounds nested rows.',
            min_length=1,
        ),
    ] = None
    concept_ids: Annotated[
        list[str] | None,
        Field(
            description='Filter by creative concept IDs. Concepts group related creatives across sizes and formats (e.g., Flashtalking concepts, Celtra campaign folders, CM360 creative groups).',
            min_length=1,
        ),
    ] = None
    format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Filter legacy named-format creatives. Use `format_kinds` for canonical libraries.',
            min_length=1,
        ),
    ] = None
    format_kinds: Annotated[
        list[str] | None,
        Field(
            description='Filter by canonical format kinds. Returns creatives matching any supplied kind.',
            min_length=1,
        ),
    ] = None
    asset_types: Annotated[
        list[asset_content_type.AssetContentType] | None,
        Field(
            description="Filter by asset types present on direct object values in the creative's top-level `assets` map. A creative matches when any directly assigned object has an `asset_type` in this array (OR within this field); this filter is conjunctive with every other active filter (AND across fields). Do not inspect array-valued slots or recurse into nested asset fields such as `cards[].media`; broader traversal is deferred. Agents that do not implement this filter MUST ignore it and apply the remaining filters rather than reject the request. Exact asset-type values use the shared AssetContentType vocabulary; `published_post` selects existing-published-post reference creatives without relying on publisher-specific format IDs.",
            min_length=1,
        ),
    ] = None
    has_variables: Annotated[
        StrictBool | None,
        Field(
            description='When true, return only creatives with dynamic variables (DCO). When false, return only static creatives.'
        ),
    ] = None
    ext: Annotated[
        ext_1.ExtensionObject | None,
        Field(
            description='Vendor-namespaced extension parameters for seller- or platform-specific creative filter criteria not covered by standard fields. Keys MUST be namespaced under a vendor or platform key (e.g., ext.gam, ext.platform_x). Sellers MUST treat all values as untrusted buyer input; avoid unbounded logging or labels, and do not interpolate values into caller-visible error strings, LLM prompts, SQL queries, or system commands without sanitization. Persistent use of an extension key across multiple buyers is a signal to propose standardization.'
        ),
    ] = 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 accounts : list[AccountReference1 | AccountReference2] | None
var asset_types : list[AssetContentType] | None
var assigned_to_packages : list[str] | None
var concept_ids : list[str] | None
var created_after : pydantic.types.AwareDatetime | None
var created_before : pydantic.types.AwareDatetime | None
var creative_ids : list[str] | None
var ext : ExtensionObject | None
var format_ids : list[FormatReferenceStructuredObject] | None
var format_kinds : list[str] | None
var has_served : bool | None
var has_variables : bool | None
var indicator_types : list[IndicatorType] | None
var media_buy_ids : list[str] | None
var model_config
var name_contains : str | None
var statuses : list[CreativeStatus] | None
var tags : list[str] | None
var tags_any : list[str] | None
var unassigned : bool | None
var updated_after : pydantic.types.AwareDatetime | None
var updated_before : pydantic.types.AwareDatetime | None

Inherited members

class CreativeItem1 (**data: Any)
Expand source code
class CreativeItem1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_kind: Annotated[
        Literal['media'],
        Field(description='Discriminator indicating this is a media asset with content_uri'),
    ] = 'media'
    asset_type: Annotated[
        str,
        Field(
            description='Type of asset. Common types: thumbnail_image, product_image, featured_image, logo'
        ),
    ]
    asset_id: Annotated[
        str, Field(description='Unique identifier for the asset within the creative')
    ]
    content_uri: Annotated[AnyUrl, Field(description='URL for media assets (images, videos, etc.)')]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_id : str
var asset_kind : Literal['media']
var asset_type : str
var content_uri : pydantic.networks.AnyUrl
var model_config

Inherited members

class CreativeItem2 (**data: Any)
Expand source code
class CreativeItem2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_kind: Annotated[
        Literal['text'],
        Field(description='Discriminator indicating this is a text asset with content'),
    ] = 'text'
    asset_type: Annotated[
        str,
        Field(
            description='Type of asset. Common types: headline, body_text, cta_text, price_text, sponsor_name, author_name, click_url'
        ),
    ]
    asset_id: Annotated[
        str, Field(description='Unique identifier for the asset within the creative')
    ]
    content: Annotated[
        str | list[str],
        Field(
            description='Text content for text-based assets like headlines, body text, CTA text, etc.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_id : str
var asset_kind : Literal['text']
var asset_type : str
var content : str | list[str]
var model_config

Inherited members

class CreativeLocalePolicy (**data: Any)
Expand source code
class CreativeLocalePolicy(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    accepted_language_ranges: Annotated[
        list[locale_tag.LanguageTag],
        Field(
            description='Concrete canonical BCP 47 language ranges accepted by this format option. RFC 4647 Basic Filtering is directional: seller range fr accepts variant fr-CA, but seller range fr-CA does not accept variant fr or fr-FR. Use zxx explicitly for language-neutral creative; und means unknown and is not a wildcard.',
            max_length=50,
            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 accepted_language_ranges : list[LanguageTag]
var model_config

Inherited members

class CreativeLocalization (**data: Any)
Expand source code
class CreativeLocalization(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    source: Annotated[
        Source,
        Field(
            description="Identity and locale of the source variant. Its asset payload is the parent creative's top-level `assets` object. Source identifies production provenance; it is not implicitly the serving default."
        ),
    ]
    target_variants: Annotated[
        list[TargetVariant],
        Field(
            description='Complete desired target-locale set for this creative. May be empty for a monolingual source-only creative. Every target contains materialized locale-specific asset overrides. Missing slots inherit source assets; after inheritance every resolved variant MUST satisfy the selected creative format.',
            max_length=50,
            min_length=0,
        ),
    ]
    locale_fallbacks: Annotated[
        list[LocaleFallback] | None,
        Field(
            description='Optional explicit language-family substitutions evaluated only when strict RFC 4647 Lookup finds no equal available tag for the current requested preference. For each preference in order, the seller checks progressively truncated ranges from most to least specific and applies the first rule whose language_range equals that candidate. A rule may map a regional request to a different materialized regional variant, but no substitution is inferred when a rule is absent.',
            max_length=50,
            min_length=1,
        ),
    ] = None
    default_locale_variant_id: Annotated[
        str,
        Field(
            description='The source or target locale_variant_id used when neither strict RFC 4647 Lookup nor an explicit locale_fallbacks rule matches and unmatched_locale_action is serve_default.',
            max_length=255,
            min_length=1,
        ),
    ]
    unmatched_locale_action: Annotated[
        UnmatchedLocaleAction,
        Field(
            description='Required seller behavior when neither strict RFC 4647 Lookup nor an explicit locale_fallbacks rule matches. serve_default serves default_locale_variant_id; do_not_serve makes this creative ineligible for that opportunity.'
        ),
    ]

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 default_locale_variant_id : str
var locale_fallbacks : list[LocaleFallback] | None
var model_config
var source : Source
var target_variants : list[TargetVariant]
var unmatched_locale_action : UnmatchedLocaleAction

Inherited members

class CreativeLocalizationReadback (**data: Any)
Expand source code
class CreativeLocalizationReadback(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    default_locale_variant_id: Annotated[
        str,
        Field(
            description='The source or target locale variant used after strict Lookup and explicit fallback rules both miss when unmatched_locale_action is serve_default.',
            max_length=255,
            min_length=1,
        ),
    ]
    unmatched_locale_action: Annotated[
        UnmatchedLocaleAction,
        Field(
            description='Final action after strict Lookup and explicit locale_fallbacks both miss.'
        ),
    ]
    locale_matching: Annotated[
        Literal['rfc4647_lookup'],
        Field(
            description="Strict RFC 4647 section 3.4 Lookup applied to an ordered language-preference list supplied by the seller's serving environment. AdCP does not carry or define how that list is derived. The seller progressively truncates each requested range and matches only an available canonical tag equal to that range; it does not prefix-match sibling regional tags."
        ),
    ] = 'rfc4647_lookup'
    locale_fallbacks: Annotated[
        list[LocaleFallback] | None,
        Field(
            description='Exact buyer-declared language-family substitutions preserved from sync. For each requested preference, rules are checked from the most specific progressively truncated range to the least specific only after strict Lookup finds no equal available tag for that preference.',
            max_length=50,
            min_length=1,
        ),
    ] = None
    variants: Annotated[
        list[Variants],
        Field(
            description='The source variant followed by every target variant, or only the source for monolingual topology. Assets are fully resolved after source inheritance. The enclosing creative status applies to the set as a whole.',
            max_length=51,
            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 default_locale_variant_id : str
var locale_fallbacks : list[LocaleFallback] | None
var locale_matching : Literal['rfc4647_lookup']
var model_config
var unmatched_locale_action : UnmatchedLocaleAction
var variants : list[Variants1 | Variants2]

Inherited members

class CreativeManifest (**data: Any)
Expand source code
class CreativeManifest(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )

    @model_validator(mode='before')
    @classmethod
    def _coerce_standalone_assets(cls, data: Any) -> Any:
        if not isinstance(data, dict) or not isinstance(data.get('assets'), dict):
            return data
        return {
            **data,
            'assets': {key: _normalize_asset_models(value) for key, value in data['assets'].items()},
        }

    format_id: Annotated[
        format_id_1.FormatReferenceStructuredObject | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format path retained for 3.x compatibility. New manifests use canonical `format_kind` and, when product routing requires it, `format_option_ref`. Mutually exclusive with format_kind.',
        ),
    ] = None
    format_kind: Annotated[
        str | None,
        Field(
            description="Canonical 3.2 path. The canonical format name this manifest targets (e.g., `image`, `video_hosted`, `audio_vast`, `seller_rendered_stateful_display`, `coordinated_placements`). Selects the contract against which the seller validates the manifest's assets. Mutually exclusive with deprecated `format_id`."
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='3.1+ format-option path, optional. Structured format option reference matching one of the target product\'s `format_options[]` declarations. Publisher-catalog-backed options match by `{ scope: "publisher", publisher_domain, format_option_id }`; product-local options match by `{ scope: "product", format_option_id }`. Required when the target product carries multiple `format_options` entries sharing the same `format_kind`; optional when `format_kind` alone routes the manifest to a single declaration. Product-scoped refs require an enclosing target product/package context.'
        ),
    ] = None
    representation_selection: Annotated[
        representation_selection_1.RepresentationSelection | None,
        Field(
            description='Present when this seller-bound manifest was selected from a CreativeRepresentationSet. Preserves creative, complete revision digest, and selected representation lineage through sync and reporting.'
        ),
    ] = None
    assets: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')], asset_union.AssetVariant | Assets],
        Field(
            description="Map of slot keys to actual asset content. Legacy named-format path: each key matches an `asset_id` from the format's `assets` array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). 3.1+ canonical-format path: each key matches an `asset_group_id` from the format's `slots` declaration drawn from the canonical vocabulary registry (e.g., 'images_landscape', 'video', 'published_post', 'landing_page_url', 'vast_tag', 'script', 'creative_brief'). Either path produces the same envelope shape; only the slot-key vocabulary differs.\n\nEach slot value is **either** a single asset object (most slots — image, video, published_post, vast_tag, landing_page_url, etc.) **or** an array of asset objects (slots with `min`/`max` counts on the format declaration — `cards` on `image_carousel`, `headlines` / `descriptions` / `images_landscape` on `responsive_creative`, etc.). Single-vs-array shape is governed by the format's `slots[].min` and `slots[].max` parameters: when `max > 1` (or when the slot is conceptually a pool), the value MUST be an array; when the slot is single-valued, the value MUST be a single object. Each asset value (single or array element) carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog, published_post, zip, card) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches."
        ),
    ]
    component_assets: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[a-z][a-z0-9_]*$')], creative_assets.CreativeAssets] | None,
        Field(
            description="Component-addressed asset maps for `coordinated_placements`. Each key MUST match one `params.components[].component_id`; its value supplies that component's canonical slots. Shared assets remain in top-level `assets` and are injected only into components named by `shared_slots[].consumed_by`. This namespace allows two components to use the same canonical slot name, such as `image_main`, without collision. It MUST be absent for non-`coordinated_placements` manifests."
        ),
    ] = None
    brand: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description="Brand identity reference (BrandRef — `domain` plus optional `brand_id` for house-of-brands; plus optional inline `brand_kit_override` for per-creative tweaks where brand.json is missing/stale). When present, the seller pulls master brand identity (logo, palette, fonts, voice, and visual guidelines) from the brand's brand.json automatically; supported fields present in `brand_kit_override` take precedence, and all other master identity fields continue to come from brand.json. Catalogs supply product or item payload. Catalog item asset groups — including an item-level `logo` for a property or franchise — are item identity selected through format field bindings; they do not override brand.json's master logo or other brand identity fields. v2 formats no longer redeclare brand_logo / brand_colors / brand_voice as explicit slots — brand identity is implicit context."
        ),
    ] = None
    rights: Annotated[
        list[rights_constraint.RightsConstraint] | None,
        Field(
            description='Rights constraints attached to this creative. Buyer-carried fields are informational until a serving party evaluates an issuer-bound attestation reference under its own policy. Only a verified, unexpired, unrevoked, digest-matched evaluation can support serving authorization; verification_url is never authority.'
        ),
    ] = None
    industry_identifiers: Annotated[
        list[industry_identifier.IndustryIdentifier] | None,
        Field(
            description='Industry-standard or market-specific identifiers for this specific manifest (e.g., Ad-ID, ISCI, Clearcast clock number, IDcrea). When present, overrides creative-level identifiers. Use when different format versions of the same source creative have distinct traffic identifiers (e.g., the :15 and :30 cuts, or separate TV and radio versions). Add a PR to extend creative-identifier-type when another shared identifier scheme needs first-class support.'
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this creative manifest. Serves as the default provenance for all assets in this manifest. An asset with its own provenance replaces this object entirely (no field-level merging).'
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None

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

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 assets : dict[str, ImageAsset | VideoAsset | AudioAsset | VastAsset | DisplayTagAsset | TextAsset | UrlAsset | HtmlAsset | JavascriptAsset | ZipAsset | WebhookAsset | CssAsset | DaastAsset | MarkdownAsset | BriefAsset | CatalogAsset | PublishedPostAsset | CardAsset | PixelTrackerAsset | VastTrackerAsset | DaastTrackerAsset | Assets]
var brand : BrandReference | None
var component_assets : dict[str, CreativeAssets] | None
var ext : ExtensionObject | None
var format_kind : str | None
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var industry_identifiers : list[IndustryIdentifier] | None
var model_config
var provenance : Provenance | None
var representation_selection : RepresentationSelection | None
var rights : list[RightsConstraint] | None

Instance variables

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

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

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

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

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

Inherited members

class CreativeOperationFormatDeclaration (**data: Any)
Expand source code
class CreativeOperationFormatDeclaration(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description='Stable publisher- or product-declaration identity that this creative operation can satisfy. When publisher_domain is present, this field is required.'
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description='Publisher namespace for format_option_id when this operation claims compatibility with a publisher declaration.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Creative-route processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. These capabilities describe build, validation, or preview processing and do not grant seller production authority.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: StrictBool | None = None
    display_name: str | None = None
    sample_render_url: AnyUrl | None = None
    applies_to_channels: list[channels.MediaChannel] | None = None
    seller_preference: SellerPreference | None = None
    locale_policy: creative_locale_policy.CreativeLocalePolicy | None = None
    canonical_formats_only: StrictBool | None = False
    experimental: StrictBool | None = False
    format_shape: str | None = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None, Field(min_length=1)
    ] = None
    format_schema: platform_extension_ref.PlatformExtensionReference | None = None
    format_kind: str
    params: Annotated[
        dict[str, Any],
        Field(
            description='Canonical creative-shape parameters. Validate against the schema selected by format_kind; custom params validate against the fetched format_schema.'
        ),
    ]

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : str
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : dict[str, typing.Any]
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

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

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

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

Inherited members

class CreativeRepresentation (**data: Any)
Expand source code
class CreativeRepresentation(CreativeManifest):
    model_config = ConfigDict(
        extra='allow',
        json_schema_extra={
            'not': {
                'anyOf': [
                    {'required': ['format_id']},
                    {'required': ['format_option_ref']},
                    {'required': ['representation_selection']},
                ]
            }
        },
    )
    representation_id: Annotated[
        str,
        Field(
            description='Stable representation identifier, unique within the enclosing CreativeRepresentationSet revision.',
            min_length=1,
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]
    source: Source
    format_kind: Annotated[
        str,
        Field(
            description="Canonical 3.2 path. The canonical format name this manifest targets (e.g., `image`, `video_hosted`, `audio_vast`, `seller_rendered_stateful_display`, `coordinated_placements`). Selects the contract against which the seller validates the manifest's assets. Mutually exclusive with deprecated `format_id`."
        ),
    ]

    @model_validator(mode='before')
    @classmethod
    def _reject_seller_bound_manifest_fields(cls, data: Any) -> Any:
        """Representations cannot carry seller-side manifest selectors."""
        if isinstance(data, dict):
            forbidden = ('format_id', 'format_option_ref', 'representation_selection')
            present = [field for field in forbidden if field in data]
            if present:
                raise ValueError(
                    'creative representations must not include ' + ', '.join(present)
                )
        return data

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var format_kind : str
var model_config
var representation_id : str
var source : Source

Inherited members

class CreativeRepresentationSet (**data: Any)
Expand source code
class CreativeRepresentationSet(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    creative_id: Annotated[
        str,
        Field(
            description='Stable logical creative identifier across all representations and later seller-bound manifests.',
            min_length=1,
        ),
    ]
    revision_id: Annotated[
        creative_revision_id.CreativeRevisionId,
        Field(
            description='Buyer-assigned immutable revision identity for this complete representation set. Changing any revision-bearing part of the set requires a new revision_id; selection does not.'
        ),
    ]
    revision_content_digest: Annotated[
        str,
        Field(
            description='SHA-256 of the RFC 8785 JCS canonical revision content defined by this schema. The producer computes it over the complete representation set after removing exactly the top-level $schema, creative_id, revision_id, revision_content_digest, and name properties. `$schema` is transport/schema-location metadata and never mints creative content identity. Resolvers MUST recompute and reject a mismatch; selection readback carries the verified digest so downstream sellers bind the revision to the complete source set rather than only the selected manifest.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    name: Annotated[str, Field(min_length=1)]
    representations: Annotated[
        list[creative_representation.CreativeRepresentation],
        Field(
            description="Complete ordered set of equivalent representations. `representation_id` values MUST be unique within this array. Unsupported entries remain byte-for-byte unchanged; neither filtering nor selection changes this revision's canonical content.",
            min_length=1,
        ),
    ]
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Default provenance for every retained representation and for the selected seller-bound output unless a representation supplies a narrower provenance object.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var creative_id : str
var model_config
var name : str
var provenance : Provenance | None
var representations : list[CreativeRepresentation]
var revision_content_digest : str
var revision_id : CreativeRevisionId

Inherited members

class CreativeRevisionId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class CreativeRevisionId(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 255, 'min_length': 1}
    _json_schema_extra = {
        'description': 'Buyer-assigned identity for one immutable input-content state of a durable creative. Scoped to the parent creative_id. Seller transcoding, normalization, and delivery representations do not change this identity.',
        'title': 'Creative Revision ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class CreativeSlot (**data: Any)
Expand source code
class CreativeSlot(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    x: Annotated[SchemaInt, Field(ge=0, le=8192)]
    y: Annotated[SchemaInt, Field(ge=0, le=8192)]
    width: Annotated[SchemaInt, Field(ge=1, le=8192)]
    height: Annotated[SchemaInt, Field(ge=1, le=8192)]
    fit: Annotated[
        Fit,
        Field(
            description='How the creative render is scaled into the slot. contain preserves the whole render, cover fills and crops, and stretch fills without preserving aspect ratio.'
        ),
    ]
    clip: Annotated[
        Literal[True],
        Field(description='Slot overflow is always clipped so composition is deterministic.'),
    ]

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 clip : Literal[True]
var fit : Fit
var height : int
var model_config
var width : int
var x : int
var y : int

Inherited members

class CreativeVariable (**data: Any)
Expand source code
class CreativeVariable(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    variable_id: Annotated[str, Field(description='Variable identifier on the creative platform')]
    name: Annotated[str, Field(description='Human-readable variable name')]
    variable_type: Annotated[
        VariableType,
        Field(
            description='Data type of the variable. Each type represents a semantic content slot: text (headlines, body copy), image/video/audio (media URLs), url (clickthrough or tracking URLs), number (prices, counts), boolean (conditional flags like show_discount or is_raining), color (hex color values), date (ISO 8601 date-time for countdowns and offer expirations).'
        ),
    ]
    default_value: Annotated[
        str | None,
        Field(
            description='Default value used when no dynamic value is provided at serve time. All types are string-encoded: text/image/video/audio/url as literal strings, number as decimal (e.g., "42.99"), boolean as "true"/"false", color as "#RRGGBB", date as ISO 8601 (e.g., "2026-12-25T00:00:00Z").'
        ),
    ] = None
    required: Annotated[
        StrictBool | None,
        Field(description='Whether this variable must have a value for the creative to serve'),
    ] = 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 default_value : str | None
var model_config
var name : str
var required : bool | None
var variable_id : str
var variable_type : VariableType

Inherited members

class CreativeVariant (**data: Any)
Expand source code
class CreativeVariant(DeliveryMetrics):
    variant_id: Annotated[
        str,
        Field(
            description='Agent-assigned served-execution identifier. The legacy contract scopes uniqueness to the agent and creative. When the agent advertises creative.supports_revisions, the identifier is agent-unique and MUST NOT be reused for another creative, source revision, locale, or rendered manifest. A revision-capable adapter whose native platform reuses an identifier maps each distinct execution to a distinct AdCP variant_id and may retain the native identifier in ext. When that agent supports variant preview, this ID is its unambiguous lookup key.'
        ),
    ]
    revision_id: Annotated[
        creative_revision_id.CreativeRevisionId | None,
        Field(
            description='Buyer-authored input revision from which this served execution was derived. Required when that execution derives from a revision-aware creative. Historical reporting may legitimately return an older revision after list_creatives shows a newer current revision. Delivery optimization, generation, transcoding, or representation selection does not mint a revision.'
        ),
    ] = None
    locale_variant_id: Annotated[
        str | None,
        Field(
            description='Buyer-assigned locale variant that supplied the served assets. Required for every delivered variant of a localized creative, including default fallback delivery. Omitted for unlocalized creatives.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    manifest: Annotated[
        creative_manifest.CreativeManifest | None,
        Field(
            description='The rendered creative manifest for this variant — the actual output that was served, not the input assets. In 3.2 it carries canonical `format_kind`, optional `format_option_ref`, and the resolved assets (specific headline, image, video, etc. the platform selected or generated). For Tier 2, shows which asset combination was picked. For Tier 3, contains the generated assets which may differ entirely from the input brand identity. Pass to preview_creative to re-render.'
        ),
    ] = None
    generation_context: Annotated[
        GenerationContext | None,
        Field(
            description='Input signals that triggered generation of this variant (Tier 3). Describes why the platform created this specific variant. Platforms should provide summarized or anonymized signals rather than raw user input. For web contexts, may include page topic or URL. For conversational contexts, an anonymized content signal. For search, query category or intent. When the content context is managed through AdCP content standards, reference the artifact directly via the artifact field.'
        ),
    ] = 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 generation_context : GenerationContext | None
var locale_variant_id : str | None
var manifest : CreativeManifest | None
var model_config
var revision_id : CreativeRevisionId | None
var variant_id : str

Inherited members

class CredentialOrigin (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class CredentialOrigin(RootModel[AnyUrl]):
    root: AnyUrl

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[AnyUrl]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : pydantic.networks.AnyUrl
class CreditLimit (**data: Any)
Expand source code
class CreditLimit(AdCPBaseModel):
    amount: Annotated[StrictFloat, Field(ge=0.0)]
    currency: Annotated[str, Field(pattern='^[A-Z]{3}$')]

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 amount : float
var currency : str
var model_config

Inherited members

class CssAssetRequirements (**data: Any)
Expand source code
class CssAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_file_size_kb: Annotated[
        SchemaInt | None, Field(description='Maximum file size in kilobytes', 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

Class variables

var max_file_size_kb : int | None
var model_config

Inherited members

class DaastAsset1 (**data: Any)
Expand source code
class DaastAsset1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['daast'],
        Field(
            description='Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'daast'
    daast_version: Annotated[
        DaastVersion | None, Field(description='DAAST specification version')
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected audio duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[DaastTrackingEvent] | None,
        Field(description='Tracking events supported by this DAAST tag'),
    ] = None
    companion_ads: Annotated[
        StrictBool | None, Field(description='Whether companion display ads are included')
    ] = None
    transcript_url: Annotated[
        AnyUrl | None, Field(description='URL to text transcript of the audio content')
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration6] | None,
        Field(
            description='One declaration per occurrence in a field carried by this asset. URL-delivered assets declare only locator-URL occurrences; receivers do not infer declarations for tokens discovered later in a fetched document.',
            min_length=1,
        ),
    ] = None
    delivery_type: Annotated[
        Literal['url'],
        Field(description='Discriminator indicating DAAST is delivered via URL endpoint'),
    ] = 'url'
    url: Annotated[
        MacroBearingUrl,
        Field(
            description='URL endpoint returning DAAST XML. Macro delimiters remain byte-preserved and are processed only under attached occurrence declarations.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['daast']
var companion_ads : bool | None
var daast_version : DaastVersion | None
var delivery_type : Literal['url']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration6] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[DaastTrackingEvent] | None
var transcript_url : pydantic.networks.AnyUrl | None
var url : str | MacroBearingUrl1 | MacroBearingUrl2

Inherited members

class DaastAsset2 (**data: Any)
Expand source code
class DaastAsset2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['daast'],
        Field(
            description='Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'daast'
    daast_version: Annotated[
        DaastVersion | None, Field(description='DAAST specification version')
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected audio duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[DaastTrackingEvent] | None,
        Field(description='Tracking events supported by this DAAST tag'),
    ] = None
    companion_ads: Annotated[
        StrictBool | None, Field(description='Whether companion display ads are included')
    ] = None
    transcript_url: Annotated[
        AnyUrl | None, Field(description='URL to text transcript of the audio content')
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration7] | None,
        Field(
            description='One declaration per occurrence in a field carried by this asset. URL-delivered assets declare only locator-URL occurrences; receivers do not infer declarations for tokens discovered later in a fetched document.',
            min_length=1,
        ),
    ] = None
    delivery_type: Annotated[
        Literal['inline'],
        Field(description='Discriminator indicating DAAST is delivered as inline XML content'),
    ] = 'inline'
    content: Annotated[str, Field(description='Inline DAAST XML content')]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['daast']
var companion_ads : bool | None
var content : str
var daast_version : DaastVersion | None
var delivery_type : Literal['inline']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration7] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[DaastTrackingEvent] | None
var transcript_url : pydantic.networks.AnyUrl | None

Inherited members

class DaastAsset3 (**data: Any)
Expand source code
class DaastAsset3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['daast'],
        Field(
            description='Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'daast'
    daast_version: Annotated[
        daast_version_1.DaastVersion | None, Field(description='DAAST specification version')
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected audio duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[daast_tracking_event.DaastTrackingEvent] | None,
        Field(description='Tracking events supported by this DAAST tag'),
    ] = None
    companion_ads: Annotated[
        StrictBool | None, Field(description='Whether companion display ads are included')
    ] = None
    transcript_url: Annotated[
        AnyUrl | None, Field(description='URL to text transcript of the audio content')
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='One declaration per occurrence in a field carried by this asset. URL-delivered assets declare only locator-URL occurrences; receivers do not infer declarations for tokens discovered later in a fetched document.',
            min_length=1,
        ),
    ] = None
    delivery_type: Annotated[
        Literal['url'],
        Field(description='Discriminator indicating DAAST is delivered via URL endpoint'),
    ] = 'url'
    url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='URL endpoint returning DAAST XML. Macro delimiters remain byte-preserved and are processed only under attached occurrence declarations.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['daast']
var companion_ads : bool | None
var daast_version : DaastVersion | None
var delivery_type : Literal['url']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[DaastTrackingEvent] | None
var transcript_url : pydantic.networks.AnyUrl | None
var url : str | MacroBearingUrl3 | MacroBearingUrl4

Inherited members

class DaastAsset4 (**data: Any)
Expand source code
class DaastAsset4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['daast'],
        Field(
            description='Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'daast'
    daast_version: Annotated[
        daast_version_1.DaastVersion | None, Field(description='DAAST specification version')
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected audio duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[daast_tracking_event.DaastTrackingEvent] | None,
        Field(description='Tracking events supported by this DAAST tag'),
    ] = None
    companion_ads: Annotated[
        StrictBool | None, Field(description='Whether companion display ads are included')
    ] = None
    transcript_url: Annotated[
        AnyUrl | None, Field(description='URL to text transcript of the audio content')
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration12] | None,
        Field(
            description='One declaration per occurrence in a field carried by this asset. URL-delivered assets declare only locator-URL occurrences; receivers do not infer declarations for tokens discovered later in a fetched document.',
            min_length=1,
        ),
    ] = None
    delivery_type: Annotated[
        Literal['inline'],
        Field(description='Discriminator indicating DAAST is delivered as inline XML content'),
    ] = 'inline'
    content: Annotated[str, Field(description='Inline DAAST XML content')]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var asset_type : Literal['daast']
var companion_ads : bool | None
var content : str
var daast_version : DaastVersion | None
var delivery_type : Literal['inline']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration12] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[DaastTrackingEvent] | None
var transcript_url : pydantic.networks.AnyUrl | None

Inherited members

class DaastAssetRequirements (**data: Any)
Expand source code
class DaastAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    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 version set for this asset requirement.'),
    ] = 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 daast_version : DaastVersion | None
var daast_versions : DaastVersions | None
var model_config

Inherited members

class DaastEvent (*args, **kwds)
Expand source code
class DaastEvent(StrEnum):
    creativeView = 'creativeView'
    start = 'start'
    firstQuartile = 'firstQuartile'
    midpoint = 'midpoint'
    thirdQuartile = 'thirdQuartile'
    complete = 'complete'
    mute = 'mute'
    unmute = 'unmute'
    pause = 'pause'
    resume = 'resume'
    rewind = 'rewind'
    skip = 'skip'
    progress = 'progress'
    close = 'close'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var close
var complete
var creativeView
var firstQuartile
var midpoint
var mute
var pause
var progress
var resume
var rewind
var skip
var start
var thirdQuartile
var unmute
class DaastOffset (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class DaastOffset(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^(\\d{2}:[0-5]\\d:[0-5]\\d(\\.\\d{3})?|(100|\\d{1,2})%)$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class DaastTarget (*args, **kwds)
Expand source code
class DaastTarget(StrEnum):
    linear = 'linear'
    companion = 'companion'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var companion
var linear
class DaastTrackerConstraints (**data: Any)
Expand source code
class DaastTrackerConstraints(AdCPBaseModel):
    daast_event: DaastEvent | None = None
    target: DaastTarget | None = DaastTarget.linear
    offset: DaastOffset | None = None
    daast_versions: DaastVersions | 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

Subclasses

Class variables

var daast_event : DaastEvent | None
var daast_versions : DaastVersions | None
var model_config
var offset : DaastOffset | None
var target : DaastTarget | None

Inherited members

class DaastTrackingEvent (*args, **kwds)
Expand source code
class DaastTrackingEvent(StrEnum):
    impression = 'impression'
    creativeView = 'creativeView'
    start = 'start'
    firstQuartile = 'firstQuartile'
    midpoint = 'midpoint'
    thirdQuartile = 'thirdQuartile'
    complete = 'complete'
    mute = 'mute'
    unmute = 'unmute'
    pause = 'pause'
    resume = 'resume'
    rewind = 'rewind'
    skip = 'skip'
    progress = 'progress'
    clickTracking = 'clickTracking'
    customClick = 'customClick'
    close = 'close'
    error = 'error'
    viewable = 'viewable'
    notViewable = 'notViewable'
    viewUndetermined = 'viewUndetermined'
    measurableImpression = 'measurableImpression'
    viewableImpression = 'viewableImpression'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var clickTracking
var close
var complete
var creativeView
var customClick
var error
var firstQuartile
var impression
var measurableImpression
var midpoint
var mute
var notViewable
var pause
var progress
var resume
var rewind
var skip
var start
var thirdQuartile
var unmute
var viewUndetermined
var viewable
var viewableImpression
class DaastVersion (*args, **kwds)
Expand source code
class DaastVersion(StrEnum):
    field_1_0 = '1.0'
    field_1_1 = '1.1'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var field_1_0
var field_1_1
class DaastVersions (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class DaastVersions(RootModel[list[daast_version.DaastVersion]]):
    root: Annotated[list[daast_version.DaastVersion], Field(min_length=1)]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[list[DaastVersion]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[DaastVersion]
class DataProviderSignalSelector1 (**data: Any)
Expand source code
class DataProviderSignalSelector1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    data_provider_domain: Annotated[
        str,
        Field(
            description="Domain where data provider's adagents.json is hosted (e.g., 'polk.com')",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    selection_type: Annotated[
        Literal['all'],
        Field(
            description='Discriminator indicating all signals from this data provider are included'
        ),
    ] = 'all'

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 data_provider_domain : str
var model_config
var selection_type : Literal['all']

Inherited members

class DataProviderSignalSelector2 (**data: Any)
Expand source code
class DataProviderSignalSelector2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    data_provider_domain: Annotated[
        str,
        Field(
            description="Domain where data provider's adagents.json is hosted (e.g., 'polk.com')",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    selection_type: Annotated[
        Literal['by_id'],
        Field(description='Discriminator indicating selection by specific signal IDs'),
    ] = 'by_id'
    signal_ids: Annotated[
        list[SignalId],
        Field(
            description="Specific signal IDs from the data provider's published signal definitions",
            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 data_provider_domain : str
var model_config
var selection_type : Literal['by_id']
var signal_ids : list[SignalId]

Inherited members

class DataProviderSignalSelector3 (**data: Any)
Expand source code
class DataProviderSignalSelector3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    data_provider_domain: Annotated[
        str,
        Field(
            description="Domain where data provider's adagents.json is hosted (e.g., 'polk.com')",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    selection_type: Annotated[
        Literal['by_tag'], Field(description='Discriminator indicating selection by signal tags')
    ] = 'by_tag'
    signal_tags: Annotated[
        list[SignalTag],
        Field(
            description="Signal tags from the data provider's published signal definitions. Selector covers all signals with these tags",
            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 data_provider_domain : str
var model_config
var selection_type : Literal['by_tag']
var signal_tags : list[SignalTag]

Inherited members

class DataSubjectContestation (**data: Any)
Expand source code
class DataSubjectContestation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    url: AnyUrl | None = None
    email: EmailStr | None = None
    languages: list[str] | 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 email : pydantic.networks.EmailStr | None
var languages : list[str] | None
var model_config
var url : pydantic.networks.AnyUrl | None

Inherited members

class DataThroughPrecision (*args, **kwds)
Expand source code
class DataThroughPrecision(StrEnum):
    exact = 'exact'
    lower_bound = 'lower_bound'
    unknown = 'unknown'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var exact
var lower_bound
var unknown
class DateRange (**data: Any)
Expand source code
class DateRange(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    start: Annotated[date, Field(description='Start date (inclusive), ISO 8601')]
    end: Annotated[date, Field(description='End date (inclusive), ISO 8601')]

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 end : datetime.date
var model_config
var start : datetime.date

Inherited members

class DatetimeRange (**data: Any)
Expand source code
class DatetimeRange(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    start: Annotated[AwareDatetime, Field(description='Start timestamp (inclusive), ISO 8601')]
    end: Annotated[AwareDatetime, Field(description='End timestamp (inclusive), ISO 8601')]

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 end : pydantic.types.AwareDatetime
var model_config
var start : pydantic.types.AwareDatetime

Inherited members

class DaypartRequirement (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class DaypartRequirement(RootModel[Required | DaypartRequirement1]):
    root: Required | DaypartRequirement1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Union[Required, DaypartRequirement1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Required | DaypartRequirement1
class DaypartRequirement1 (**data: Any)
Expand source code
class DaypartRequirement1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    timezone_modes: Annotated[list[daypart_timezone_mode.DaypartTimezoneMode], Field(min_length=1)]
    iana_timezones: Annotated[
        list[iana_timezone.IanaTimezoneIdentifier] | None,
        Field(
            description='Exact concrete IANA timezone identifiers that must remain selectable after discovery. Valid only when timezone_modes includes iana.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var iana_timezones : list[IanaTimezoneIdentifier] | None
var model_config
var timezone_modes : list[DaypartTimezoneMode]

Inherited members

class DaypartSupport (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class DaypartSupport(RootModel[Literal[True] | DaypartSupport1]):
    root: Literal[True] | DaypartSupport1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

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

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

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

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

Ancestors

  • pydantic.root_model.RootModel[Union[Literal[True], DaypartSupport1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Literal[True] | DaypartSupport1
class DaypartSupport1 (**data: Any)
Expand source code
class DaypartSupport1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    timezone_modes: Annotated[list[daypart_timezone_mode.DaypartTimezoneMode], Field(min_length=1)]
    iana_timezones: Annotated[
        Literal[True] | IanaTimezones | None,
        Field(
            description="Concrete IANA timezone identifiers accepted by this product. true means every identifier valid in the seller's supported IANA TZDB; an array is the exact supported subset. Required when timezone_modes includes iana and forbidden otherwise."
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var iana_timezones : Literal[True] | IanaTimezones | None
var model_config
var timezone_modes : list[DaypartTimezoneMode]

Inherited members

class DaypartTarget (**data: Any)
Expand source code
class DaypartTarget(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    days: Annotated[
        list[day_of_week.DayOfWeek],
        Field(
            description='Days of week this window applies to. Use multiple days for compact targeting (e.g., monday-friday in one object).',
            min_length=1,
        ),
    ]
    start_hour: Annotated[
        SchemaInt,
        Field(
            description='Start hour (inclusive), 0-23 in 24-hour format. 0 = midnight, 6 = 6:00am, 18 = 6:00pm.',
            ge=0,
            le=23,
        ),
    ]
    end_hour: Annotated[
        SchemaInt,
        Field(
            description='End hour (exclusive), 1-24 in 24-hour format. 10 = 10:00am, 24 = midnight. Must be greater than start_hour.',
            ge=1,
            le=24,
        ),
    ]
    timezone: Annotated[
        Literal['inventory_local'] | iana_timezone.IanaTimezoneIdentifier | None,
        Field(
            description="Civil-time clock used to evaluate this window. 'inventory_local' evaluates the hours in the seller-assigned local timezone of each inventory unit that can deliver the impression, such as a screen, venue, station, or publisher property; it never means the buyer, account, or server timezone. A concrete IANA timezone identifier (for example, 'America/New_York', 'CET', or 'UTC') evaluates one shared civil-time clock across the targeted inventory. Omission defaults to 'inventory_local'. Buyers that begin with a user or account preference MUST resolve it to a concrete IANA identifier before sending the daypart; 'user_timezone' and 'account_timezone' are not wire values. For each candidate delivery instant, convert the instant into this clock and compare its resulting local day and hour with the half-open window: a skipped DST hour has no matching instants, while both occurrences of a repeated hour match. This delivery clock is independent of reporting_capabilities.timezone.",
            validate_default=True,
        ),
    ] = 'inventory_local'
    label: Annotated[
        str | None,
        Field(
            description="Optional human-readable name for this time window (e.g., 'Morning Drive', 'Prime Time')"
        ),
    ] = 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 days : list[DayOfWeek]
var end_hour : int
var label : str | None
var model_config
var start_hour : int
var timezone : Literal['inventory_local'] | IanaTimezoneIdentifier | None

Inherited members

class DeadlinePolicy (**data: Any)
Expand source code
class DeadlinePolicy(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    booking_lead_days: Annotated[
        SchemaInt | None,
        Field(description='Days before scheduled_at by which the placement must be booked', ge=0),
    ] = None
    cancellation_lead_days: Annotated[
        SchemaInt | None,
        Field(description='Days before scheduled_at by which cancellation is penalty-free', ge=0),
    ] = None
    material_stages: Annotated[
        list[MaterialStage] | None,
        Field(
            description='Default material submission stages. Items MUST be in chronological order (earliest due first). Agents compute due_at as: installment.scheduled_at minus lead_days.',
            min_length=1,
        ),
    ] = None
    business_days_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, lead_days counts business days (Mon-Fri) rather than calendar days. Defaults to false.'
        ),
    ] = 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 booking_lead_days : int | None
var business_days_only : bool | None
var cancellation_lead_days : int | None
var material_stages : list[MaterialStage] | None
var model_config

Inherited members

class DeclineProposalsInputRequired (**data: Any)
Expand source code
class DeclineProposalsInputRequired(CompactTaskInputRequired):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class DeclineProposalsSubmitted (**data: Any)
Expand source code
class DeclineProposalsSubmitted(CompactTaskSubmitted):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class DeclineProposalsWorking (**data: Any)
Expand source code
class DeclineProposalsWorking(CompactTaskWorking):
    pass

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config

Inherited members

class DegreeType (*args, **kwds)
Expand source code
class DegreeType(StrEnum):
    certificate = 'certificate'
    associate = 'associate'
    bachelor = 'bachelor'
    master = 'master'
    doctorate = 'doctorate'
    professional = 'professional'
    bootcamp = 'bootcamp'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var associate
var bachelor
var bootcamp
var certificate
var doctorate
var master
var professional
class DelegationType (*args, **kwds)
Expand source code
class DelegationType(StrEnum):
    direct = 'direct'
    delegated = 'delegated'
    ad_network = 'ad_network'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var ad_network
var delegated
var direct
class DeliveryBreakdownControls (**data: Any)
Expand source code
class DeliveryBreakdownControls(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    limit: Annotated[
        SchemaInt | None,
        Field(description='Maximum number of rows to return. Defaults to 25.', ge=1),
    ] = 25
    sort_by: Annotated[
        sort_metric.SortMetric | None,
        Field(
            description='Metric used to order rows. Falls back to spend when unavailable at this row grain; on fallback sort_direction resets to desc. Rows lacking a value for the applied sort metric order last regardless of direction.'
        ),
    ] = sort_metric.SortMetric.spend
    sort_direction: Annotated[
        sort_direction_1.SortDirection | None,
        Field(
            description='Direction for sort_by ordering. Sellers MUST apply the requested direction to the applied sort metric; direction has no availability fallback.'
        ),
    ] = sort_direction_1.SortDirection.desc

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 limit : int | None
var model_config
var sort_by : SortMetric | None
var sort_direction : SortDirection | None

Inherited members

class DeliveryForecast (**data: Any)
Expand source code
class DeliveryForecast(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    points: Annotated[
        list[forecast_point.ForecastPoint],
        Field(
            description='Forecasted delivery data points. For spend curves (default), points at ascending budget levels show how metrics scale with spend. For availability forecasts, points represent total available inventory independent of budget. See forecast_range_unit for interpretation.',
            min_length=1,
        ),
    ]
    forecast_range_unit: Annotated[
        forecast_range_unit_1.ForecastRangeUnit | None,
        Field(
            description="How to interpret the points array. 'spend' (default when omitted): points at ascending budget levels. 'availability': total available inventory, budget omitted. 'reach_freq': points at ascending reach/frequency targets. 'weekly'/'daily': metrics are per-period values. 'clicks'/'conversions': points at ascending outcome targets. 'package': each point is a distinct inventory package."
        ),
    ] = None
    method: Annotated[
        forecast_method.ForecastMethod, Field(description='Method used to produce this forecast')
    ]
    currency: Annotated[
        str,
        Field(
            description='ISO 4217 currency code for monetary values in this forecast (spend, budget)'
        ),
    ]
    demographic_system: Annotated[
        demographic_system_1.DemographicSystem | None,
        Field(
            description='Measurement system for the demographic field. Ensures buyer and seller agree on demographic notation.'
        ),
    ] = None
    demographic: Annotated[
        str | None,
        Field(
            description='Target demographic code within the specified demographic_system. For Nielsen: P18-49, M25-54, W35+. For BARB: ABC1 Adults, 16-34. For AGF: E 14-49.',
            examples=['P18-49', 'A25-54', 'W35+', 'M18-34'],
        ),
    ] = None
    measurement_source: Annotated[
        str | None,
        Field(
            description='Third-party measurement provider whose data was used to produce this forecast. Distinct from demographic_system, which specifies demographic notation — measurement_source identifies whose data produced the forecast numbers. Should be present when measured_impressions is used. Lowercase slug format.',
            examples=[
                'nielsen',
                'videoamp',
                'comscore',
                'geopath',
                'barb',
                'agf',
                'oztam',
                'kantar',
                'barc',
                'route',
                'rajar',
                'triton',
            ],
            max_length=64,
            pattern='^[a-z0-9_]+$',
        ),
    ] = None
    reach_unit: Annotated[
        reach_unit_1.ReachUnit | None,
        Field(
            description='Unit of measurement for reach and audience_size metrics in this forecast. Required for cross-channel forecast comparison.'
        ),
    ] = None
    generated_at: Annotated[
        AwareDatetime | None, Field(description='When this forecast was computed')
    ] = None
    valid_until: Annotated[
        AwareDatetime | None,
        Field(
            description='When this forecast expires. After this time, the forecast should be refreshed. Forecast expiry does not affect proposal executability.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 currency : str
var demographic : str | None
var demographic_system : DemographicSystem | None
var ext : ExtensionObject | None
var forecast_range_unit : ForecastRangeUnit | None
var generated_at : pydantic.types.AwareDatetime | None
var measurement_source : str | None
var method : ForecastMethod
var model_config
var points : list[ForecastPoint]
var reach_unit : ReachUnit | None
var valid_until : pydantic.types.AwareDatetime | None

Inherited members

class DeliveryMeasurement (**data: Any)
Expand source code
class DeliveryMeasurement(AdCPBaseModel):
    vendors: Annotated[
        list[brand_ref.BrandReference] | None,
        Field(
            description="Measurement vendors used for this product, as structured `BrandRef` identities. Multiple entries when multiple vendors play different roles (e.g., the ad server plus a separate viewability vendor like IAS or DV; or a retail-media seller plus a third-party retail measurement vendor like Circana or NielsenIQ). Each vendor's `brand.json` `agents[type='measurement']` is the discovery anchor; metric definitions live on the agent's `get_adcp_capabilities.measurement.metrics[]` block. Distinct from `performance_standards[].vendor` which carries vendor identity for *committed* metrics with thresholds — this field carries vendor identity for the overall measurement story, including non-committed-but-reported metrics.",
            min_length=1,
        ),
    ] = None
    provider: Annotated[
        str | None,
        Field(
            deprecated=True,
            description="**Deprecated as of this minor.** Free-form measurement provider description (e.g., 'Google Ad Manager with IAS viewability', 'Nielsen DAR', 'Geopath for DOOH impressions'). New implementations SHOULD use the structured `vendors` field instead. Retained for one-minor backwards compatibility; removed at the next major. When both `vendors` and `provider` are present, consumers MUST use `vendors` for vendor identity and treat `provider` as informational text.",
        ),
    ] = None
    notes: Annotated[
        str | None,
        Field(
            description="Additional details about measurement methodology in plain language (e.g., 'MRC-accredited viewability. 50% in-view for 1s display / 2s video', 'Panel-based demographic measurement updated monthly'). Free-form prose for context that doesn't fit the structured `vendors` field."
        ),
    ] = 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 model_config
var notes : str | None
var provider : str | None
var vendors : list[BrandReference] | None

Inherited members

class DeliveryMetricAggregate1 (**data: Any)
Expand source code
class DeliveryMetricAggregate1(Field0):
    scope: Literal['standard'] = 'standard'

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var scope : Literal['standard']

Inherited members

class DeliveryMetricAggregate2 (**data: Any)
Expand source code
class DeliveryMetricAggregate2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Annotated[
        Literal['vendor'],
        Field(description='Vendor-defined metric, identified by the tuple `(vendor, metric_id)`.'),
    ] = 'vendor'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description="Vendor that defines and computes this metric. The vendor's `brand.json` `agents[type='measurement']` is the canonical anchor; metric definitions live on `get_adcp_capabilities.measurement.metrics[]`."
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(description="Identifier for the metric within the vendor's vocabulary."),
    ]
    qualifier: Annotated[
        Qualifier3 | None,
        Field(
            description='Optional qualifier keys disambiguating this vendor-metric row from sibling rows under the same (vendor, metric_id) — e.g., attribution_window on a vendor outcome metric. Same closed key set as the standard branch; new keys ship explicitly.'
        ),
    ] = None
    value: Annotated[
        StrictFloat,
        Field(
            description="Aggregated vendor-attested value. Unit semantics defined by the vendor — see the vendor's measurement-agent metric definition."
        ),
    ]
    measurable_impressions: Annotated[
        StrictFloat | None,
        Field(
            description="Coverage denominator — vendor measurement is rarely 100% of delivery (only impressions where the vendor's SDK fired or panel matched). Buyers compute coverage as `measurable_impressions / impressions`. Same convention as `vendor_metric_value.measurable_impressions`.",
            ge=0.0,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var measurable_impressions : float | None
var metric_id : VendorMetricId
var model_config
var qualifier : Qualifier3 | None
var scope : Literal['vendor']
var value : float
var vendor : BrandReference

Inherited members

class DeliveryMetrics (**data: Any)
Expand source code
class DeliveryMetrics(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    impressions: Annotated[
        StrictFloat | None, Field(description='Impressions delivered', ge=0.0)
    ] = None
    spend: Annotated[StrictFloat | None, Field(description='Amount spent', ge=0.0)] = None
    clicks: Annotated[StrictFloat | None, Field(description='Total clicks', ge=0.0)] = None
    ctr: Annotated[
        StrictFloat | None,
        Field(description='Click-through rate (clicks/impressions)', ge=0.0, le=1.0),
    ] = None
    views: Annotated[
        StrictFloat | None,
        Field(
            description="Content engagements counted toward the billable view threshold. For video this is a platform-defined view event (e.g., 30 seconds or video midpoint); for audio/podcast it is a stream start; for other formats it follows the pricing model's view definition. When the package uses CPV pricing, spend = views × rate.",
            ge=0.0,
        ),
    ] = None
    completed_views: Annotated[
        StrictFloat | None,
        Field(
            description='Video/audio completions. When the package has a completed_views optimization goal with view_duration_seconds, completions are counted at that threshold rather than 100% completion.',
            ge=0.0,
        ),
    ] = None
    completion_rate: Annotated[
        StrictFloat | None,
        Field(
            description='Completion rate (completed_views/impressions). Null indicates the metric is not applicable to this package/buy (e.g. completion rate on a non-video buy).',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    conversions: Annotated[
        StrictFloat | None,
        Field(
            description='Total conversions attributed to this delivery. When by_event_type is present, this equals the sum of all by_event_type[].count entries.',
            ge=0.0,
        ),
    ] = None
    conversion_value: Annotated[
        StrictFloat | None,
        Field(
            description='Total monetary value of attributed conversions (in the reporting currency)',
            ge=0.0,
        ),
    ] = None
    commissionable_value: Annotated[
        StrictFloat | None,
        Field(
            description='Settled portion of attributed conversion value eligible for revenue-share commission, in the reporting currency. For revenue_share pricing, spend = round_currency(commissionable_value × commission_rate). This is distinct from conversion_value because taxes, shipping, discounts, returns, cancellations, or ineligible items may be excluded under the agreed commission basis.',
            ge=0.0,
        ),
    ] = None
    roas: Annotated[
        StrictFloat | None,
        Field(description='Return on ad spend (conversion_value / spend)', ge=0.0),
    ] = None
    cost_per_acquisition: Annotated[
        StrictFloat | None, Field(description='Cost per conversion (spend / conversions)', ge=0.0)
    ] = None
    new_to_brand_rate: Annotated[
        StrictFloat | None,
        Field(
            description='Fraction of `conversions` (transactions) from first-time brand buyers, 0 = none, 1 = all. For retail-media unit-volume tracking of first-time buyers, see `new_to_brand_units` (count, not rate).',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    leads: Annotated[
        StrictFloat | None,
        Field(
            description="Leads generated (convenience alias for by_event_type where event_type='lead')",
            ge=0.0,
        ),
    ] = None
    incremental_sales_lift: Annotated[
        StrictFloat | None,
        Field(
            description="Incremental sales lift attributed to the campaign — sales above the control/holdout baseline. Reported as a fraction (0.15 = 15% lift) or as an absolute value depending on seller convention. The seller's `attribution_methodology` qualifier (typically `deterministic_purchase` or `modeled`) and `attribution_window` qualifier on the matching `committed_metrics` entry disambiguate the methodology and window.",
            ge=0.0,
        ),
    ] = None
    brand_lift: Annotated[
        StrictFloat | None,
        Field(
            description="Brand lift — measured change in a brand metric (awareness, consideration, favorability, purchase intent, or ad recall) attributed to the campaign. Typically panel-based or survey-based. Reported as a fraction (0.05 = 5% lift). **Multidimensional in production** — Kantar, Upwave, Cint, DV all report each dimension separately with its own sample size and confidence interval. The dimension flows through `qualifier.lift_dimension` on `committed_metrics` / `by_package[].metric_values` (`awareness` | `consideration` | `favorability` | `purchase_intent` | `ad_recall`); rows under different dimensions are different surveyed outcomes and must not be combined. Use `attribution_methodology: 'panel_based'` qualifier when the underlying methodology is a panel.",
            ge=0.0,
        ),
    ] = None
    foot_traffic: Annotated[
        StrictFloat | None,
        Field(
            description="Store visits attributed to ad exposure. Count of incremental visits over baseline. Typically uses location-data panel methodology (`attribution_methodology: 'panel_based'`) or deterministic loyalty-card match (`attribution_methodology: 'deterministic_purchase'`).",
            ge=0.0,
        ),
    ] = None
    conversion_lift: Annotated[
        StrictFloat | None,
        Field(
            description='Incremental conversions attributed to the campaign — conversions above the control/holdout baseline. Reported as a fraction (0.10 = 10% lift) or as an absolute count depending on seller convention. Distinct from `conversions` (raw count of attributed conversions); conversion_lift requires a control group and an incrementality methodology.',
            ge=0.0,
        ),
    ] = None
    brand_search_lift: Annotated[
        StrictFloat | None,
        Field(
            description='Lift in brand search query volume attributed to the campaign — measured via search-data partnerships (Google, Microsoft) or survey methodology. Reported as a fraction (0.20 = 20% lift in branded search).',
            ge=0.0,
        ),
    ] = None
    plays: Annotated[
        StrictFloat | None,
        Field(
            description="Number of times the ad creative was displayed or played on DOOH or broadcast inventory. Raw play count before any impression multiplier is applied. Mirrors `forecastable-metric.json`'s `plays` token for forecast↔delivery reconciliation. Distinct from `dooh_metrics.loop_plays` (scheduled-rotation count) and from `impressions` (multiplied audience figure).",
            ge=0.0,
        ),
    ] = None
    measurement_source: Annotated[
        str | None,
        Field(
            description="Third-party measurement provider whose data produced this row's audience numbers. Mirrors delivery-forecast.json's measurement_source so forecast and delivery reconcile on the same declaration — distinct from demographic_system, which specifies demographic notation. Makes measured-channel rows (radio, broadcast, OOH) self-describing: a reconciliation join can tie delivered numbers to the system that measured them without consulting out-of-band context. Lowercase slug format.",
            examples=[
                'nielsen',
                'nielsen_audio',
                'videoamp',
                'comscore',
                'geopath',
                'barb',
                'agf',
                'oztam',
                'kantar',
                'barc',
                'route',
                'rajar',
                'triton',
            ],
            max_length=64,
            pattern='^[a-z0-9_]+$',
        ),
    ] = None
    by_event_type: Annotated[
        list[ByEventTypeItem] | None,
        Field(
            description='Conversion metrics broken down by event type. Spend-derived metrics (ROAS, CPA) are only available at the package/totals level since spend cannot be attributed to individual event types.'
        ),
    ] = None
    grps: Annotated[
        StrictFloat | None, Field(description='Gross Rating Points delivered (for CPP)', ge=0.0)
    ] = None
    reach: Annotated[
        StrictFloat | None,
        Field(
            description='Unique reach in the units specified by reach_unit. When reach_unit is omitted, units are unspecified — do not compare reach values across packages or media buys without a common reach_unit. The measurement window for this value is declared in `reach_window`; when `reach_window` is omitted, the window is unspecified and buyers MUST NOT sum reach across reports (the value MAY be a daily snapshot, a cumulative total, or something else).',
            ge=0.0,
        ),
    ] = None
    reach_unit: Annotated[
        reach_unit_1.ReachUnit | None,
        Field(
            description='Unit of measurement for the reach field. Aligns with the reach_unit declared on optimization goals and delivery forecasts. Required when reach is present to enable cross-platform comparison.'
        ),
    ] = None
    reach_window: Annotated[
        ReachWindow | None,
        Field(
            description='Measurement window for the reported `reach` and `frequency` values in this row. Declares whether the values are a per-period snapshot, a trailing rolling window, or cumulative-to-date — without this declaration, buyers summing `reach` across rows (e.g., daily delivery reports) can silently double-count audiences. Sellers SHOULD populate this whenever `reach` is present.'
        ),
    ] = None
    frequency: Annotated[
        StrictFloat | None,
        Field(
            description="Average frequency per reach unit, measured over the window declared in `reach_window`. When `reach_unit` is 'households', this is average exposures per household; when 'accounts', per logged-in account; etc. When `reach_window` is omitted, the window is unspecified — buyers MUST NOT compare or average frequency values across rows.",
            ge=0.0,
        ),
    ] = None
    quartile_data: Annotated[
        QuartileData | None,
        Field(
            description="Audio/video quartile completion data. Null indicates the metric is not applicable to this package/buy (e.g. quartile data on a non-video buy). Individual quartiles are addressable via the leaf metric identities `quartile_25` (q1_views), `quartile_50` (q2_views), `quartile_75` (q3_views), and `quartile_100` (q4_views) for declaration, commitments, aggregates, and breakdown sorting; this object remains the canonical carrier of the values. Quartiles are player-fired events (VAST firstQuartile/midpoint/thirdQuartile/complete). `quartile_100` counts 100%-of-duration completions and is distinct from `completed_views`, which counts completions at the seller's billable view threshold (`view_duration_seconds`) when one is set."
        ),
    ] = None
    time_based_views: Annotated[
        list[TimeBasedView] | None,
        Field(
            description="Time-threshold video view counts. Each entry reports views that met a continuous duration threshold under a stated basis, rather than a completion percentage (percentage-based completion is quartile_data). Thresholds of 2 and 6 seconds are RECOMMENDED cross-platform reporting points; any seller-defined threshold is permitted. One entry per (threshold_seconds, basis) pair per reporting period — sellers MUST de-duplicate before emission and MUST NOT emit the same pair twice; buyers MAY treat duplicate pairs as a seller-side conformance bug. Entries under different bases are different metrics and MUST NOT be summed (see view-threshold-basis). Primarily an autoplay/skippable-video metric (social, olv, in-feed video); completion metrics remain the currency for lean-back CTV/cinema inventory. Distinct from `views` (the single billable-threshold scalar) and from `viewability.viewed_seconds` (average in-view duration, not a threshold count). Array entries are not individually sortable in breakdown sort_by. Disclosure-grade surface: (threshold_seconds, basis) is not part of the committed-metric qualifier vocabulary, so a `committed_metrics` entry for `time_based_views` contracts the array's presence, not specific thresholds."
        ),
    ] = None
    dooh_metrics: Annotated[
        DoohMetrics1 | None,
        Field(description='DOOH-specific metrics (only included for DOOH campaigns)'),
    ] = None
    ooh_metrics: Annotated[
        OohMetrics | None,
        Field(
            description='Classic (static) OOH metrics — printed bulletins, posters, transit, and street furniture (only included for ooh campaigns). Experimental in AdCP 3.2. Static units have no play event: the delivery number is a period-level modeled audience estimate whose methodology tier is declared in estimation_basis (provider identity rides the row-level measurement_source), and the settlement artifact is the posting record — it proves the posting period, not an airing.'
        ),
    ] = None
    viewability: Annotated[
        Viewability1 | None,
        Field(
            description="Viewability metrics. Viewable rate should be calculated as viewable_impressions / measurable_impressions (not total impressions), since some environments cannot measure viewability. Includes `viewed_seconds` — average in-view duration — plus optional percentile and histogram distributions over that duration; all three use the same `measurable_impressions` population and are governed by the same viewability threshold (`standard`). Sellers SHOULD include `standard` whenever measured viewability values are reported because MRC and GroupM rows are not interchangeable. The numeric leaves are addressable via the leaf metric identities `viewable_rate`, `viewable_impressions`, `measurable_impressions`, and `viewed_seconds` for declaration, commitments, aggregates, and breakdown sorting. The structured distribution carriers require explicit `viewed_seconds_percentiles` and `viewed_seconds_histogram` identities for declaration, commitment, and selection; they are not numeric aggregate rows or sort keys. This object remains the canonical carrier of every value. When a buy reports under more than one standard, contract a specific standard via the `viewability_standard` qualifier on `committed_metrics`; when the package's `committed_metrics` carry a `viewability_standard` qualifier, sellers MUST populate `standard` on reported viewability objects so reconciliation can match the qualifier."
        ),
    ] = None
    engagements: Annotated[
        StrictFloat | None,
        Field(
            description="Total engagements — direct interactions with the ad beyond viewing. Includes social reactions/comments/shares, story/unit opens, interactive overlay taps on CTV, companion banner interactions on audio. Platform-specific; corresponds to the 'engagements' optimization metric. Maps to DBCFM KPI_INTERACTIONS (Interaktionen) in the Reporting/Performance block.",
            ge=0.0,
        ),
    ] = None
    follows: Annotated[
        StrictFloat | None,
        Field(
            description='New followers, page likes, artist/podcast/channel follows, or free channel/feed subscribes attributed to this delivery. Paid subscriptions are conversion events with `event_type: subscribe`, not `follows`.',
            ge=0.0,
        ),
    ] = None
    saves: Annotated[
        StrictFloat | None,
        Field(
            description='Saves, bookmarks, playlist adds, pins attributed to this delivery.', ge=0.0
        ),
    ] = None
    profile_visits: Annotated[
        StrictFloat | None,
        Field(
            description="Visits to the brand's in-platform page (profile, artist page, channel, or storefront) attributed to this delivery. Does not include external website clicks.",
            ge=0.0,
        ),
    ] = None
    engagement_rate: Annotated[
        StrictFloat | None,
        Field(
            description='Platform-specific engagement rate (0.0 to 1.0). Typically engagements/impressions, but definition varies by platform.',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    cost_per_click: Annotated[
        StrictFloat | None, Field(description='Cost per click (spend / clicks)', ge=0.0)
    ] = None
    cost_per_completed_view: Annotated[
        StrictFloat | None,
        Field(
            description="Cost per completed view (spend / completed_views). Primary CPCV pricing scalar for video/audio inventory; the package's `pricing_model` is `cpcv` when this field is the billing basis.",
            ge=0.0,
        ),
    ] = None
    cpm: Annotated[
        StrictFloat | None,
        Field(
            description="Cost per thousand impressions, computed as (spend / impressions) × 1000. Universal pricing scalar across CTV, display, mobile/web video, native, audio, and DOOH inventory; the package's `pricing_model` is `cpm` when this field is the billing basis. Field name aligns with the canonical `cpm` token in `enums/pricing-model.json` and `pricing-options/cpm-option.json` so buyers cross-walk pricing model → reported scalar without a translation table.",
            ge=0.0,
        ),
    ] = None
    downloads: Annotated[
        StrictFloat | None,
        Field(
            description="Audio/podcast downloads (IAB Podcast Measurement Technical Guidelines 2.x methodology). Distinct from `views` — for podcast inventory this is the count of podcast episode downloads; for streaming audio it is the count of stream starts that meet the platform's download threshold. Prefer this over `views` for audio inventory.",
            ge=0.0,
        ),
    ] = None
    units_sold: Annotated[
        StrictFloat | None,
        Field(
            description='Items sold attributed to this delivery. Retail-media scalar distinct from `conversions` — a single conversion (transaction) may carry multiple `units_sold`. Used by retail media platforms where the buyer optimizes against unit movement, not transaction count. Attribution lookback windows are platform-specific (commonly 7/14/30 days, view-through and click-through variants); sellers SHOULD declare the window via `reporting_capabilities.measurement_windows` or `measurement_terms` rather than encoding it in this scalar.',
            ge=0.0,
        ),
    ] = None
    new_to_brand_units: Annotated[
        StrictFloat | None,
        Field(
            description='Units sold to first-time brand buyers (count, not rate). Retail-media scalar — the unit-volume parallel to the conversion-fraction `new_to_brand_rate`. Used by retail media platforms where new-customer acquisition unit volume is a primary KPI. Same attribution-window note as `units_sold` applies.',
            ge=0.0,
        ),
    ] = None
    by_action_source: Annotated[
        list[ByActionSourceItem] | None,
        Field(
            description='Conversion metrics broken down by action source (website, app, in_store, etc.). Useful for omnichannel sellers where conversions occur across digital and physical channels.'
        ),
    ] = None
    vendor_metric_values: Annotated[
        list[vendor_metric_value.VendorMetricValue] | None,
        Field(
            description="Reported values for vendor-defined metrics that the product's `reporting_capabilities.vendor_metrics` declared. Each entry carries the vendor (BrandRef), the metric identifier within the vendor's vocabulary, the value, optional unit, and `measurable_impressions` as the coverage denominator — vendor measurement is rarely 100% of delivered impressions, since vendors only score impressions where their SDK fires or their panel matches. When a declared vendor metric is omitted from this array, buyers infer no measurement happened (no integration). One row per `(vendor.domain, vendor.brand_id, metric_id, qualifier)` per reporting period — the same vendor metric MAY appear in multiple rows only when each carries a distinct qualifier (e.g., 7-day and 30-day attribution windows); sellers MUST de-duplicate before emission and MUST NOT emit two rows with the same tuple; buyers MAY treat duplicate rows as a seller-side conformance bug. The structured `vendor_metric_values` array is the recommended path for vendor metrics; `additionalProperties: true` on this parent object is preserved so existing free-form vendor emissions remain conformant during migration."
        ),
    ] = 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 brand_lift : float | None
var brand_search_lift : float | None
var by_action_source : list[ByActionSourceItem] | None
var by_event_type : list[ByEventTypeItem] | None
var clicks : float | None
var commissionable_value : float | None
var completed_views : float | None
var completion_rate : float | None
var conversion_lift : float | None
var conversion_value : float | None
var conversions : float | None
var cost_per_acquisition : float | None
var cost_per_click : float | None
var cost_per_completed_view : float | None
var cpm : float | None
var ctr : float | None
var dooh_metrics : DoohMetrics1 | None
var downloads : float | None
var engagement_rate : float | None
var engagements : float | None
var follows : float | None
var foot_traffic : float | None
var frequency : float | None
var grps : float | None
var impressions : float | None
var incremental_sales_lift : float | None
var leads : float | None
var measurement_source : str | None
var model_config
var new_to_brand_rate : float | None
var new_to_brand_units : float | None
var ooh_metrics : OohMetrics | None
var plays : float | None
var profile_visits : float | None
var quartile_data : QuartileData | None
var reach : float | None
var reach_unit : ReachUnit | None
var reach_window : ReachWindow | None
var roas : float | None
var saves : float | None
var spend : float | None
var time_based_views : list[TimeBasedView] | None
var units_sold : float | None
var vendor_metric_values : list[VendorMetricValue] | None
var viewability : Viewability1 | None
var views : float | None

Inherited members

class DeliveryProvider (**data: Any)
Expand source code
class DeliveryProvider(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    domain: Annotated[
        str,
        Field(
            description="Lowercase dotted provider domain, such as a provider's operating domain. Single-label and localhost-style names are invalid.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$',
        ),
    ]

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 domain : str
var model_config

Inherited members

class DeliveryRecipient (**data: Any)
Expand source code
class DeliveryRecipient(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    identity: Annotated[str, Field(max_length=512, min_length=1)]
    cloud: delivery_recipient_cloud.DeliveryRecipientCloud | None = None
    region: Annotated[str | None, Field(max_length=128, min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var cloud : DeliveryRecipientCloud | None
var identity : str
var model_config
var region : str | None

Inherited members

class DemographicAgeRange (**data: Any)
Expand source code
class DemographicAgeRange(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    min: Annotated[
        SchemaInt | None,
        Field(
            description='Inclusive minimum age in completed years. Omit for an open lower bound.',
            ge=0,
            le=150,
        ),
    ] = None
    max: Annotated[
        SchemaInt | None,
        Field(
            description='Inclusive maximum age in completed years. Omit for an open upper bound.',
            ge=0,
            le=150,
        ),
    ] = None
    include_unknown: Annotated[
        StrictBool,
        Field(
            description='Whether delivery to people whose age is unavailable is part of this predicate. This field has no default and MUST be supplied.'
        ),
    ]

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> DemographicAgeRange:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('min',), ('max',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'DemographicAgeRange requires at least one of these field groups: min | max'
        )

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 include_unknown : bool
var max : int | None
var min : int | None
var model_config

Inherited members

class DemographicPredicate (**data: Any)
Expand source code
class DemographicPredicate(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    age: demographic_age_range.DemographicAgeRange

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 age : DemographicAgeRange
var model_config

Inherited members

class DemographicReportingCapability (**data: Any)
Expand source code
class DemographicReportingCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    age: Annotated[
        Age | None, Field(description='Machine-comparable age ranges this product can report.')
    ] = None
    demographic_systems: Annotated[
        list[demographic_system_1.DemographicSystem] | None,
        Field(
            description='Measurement-system notations this product may return. A code remains opaque unless its capability interval and response row also carry a canonical age predicate.',
            min_length=1,
        ),
    ] = None
    may_suppress_small_cells: Annotated[
        StrictBool,
        Field(
            description='Whether privacy, policy, or measurement thresholds may suppress otherwise reportable demographic rows. When true, buyers must inspect by_demographic_suppressed before testing whether rows reconcile to package totals.'
        ),
    ]

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> DemographicReportingCapability:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('age',), ('demographic_systems',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'DemographicReportingCapability requires at least one of these field groups: age | demographic_systems'
        )

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 age : Age | None
var demographic_systems : list[DemographicSystem] | None
var may_suppress_small_cells : bool
var model_config

Inherited members

class DemographicTargetingCapability (**data: Any)
Expand source code
class DemographicTargetingCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    age: Annotated[Age, Field(description='Age-targeting execution available for this product.')]

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 age : Age
var model_config

Inherited members

class DemographicTargetingIntent (**data: Any)
Expand source code
class DemographicTargetingIntent(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    age: Age

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 age : Age
var model_config

Inherited members

class DemographicTargetingResolution (**data: Any)
Expand source code
class DemographicTargetingResolution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    requested: Annotated[
        demographic_targeting_intent.DemographicTargetingIntent,
        Field(
            description='Canonical demographic predicate and determination constraints requested by the buyer.'
        ),
    ]
    applied: Annotated[
        demographic_predicate.DemographicPredicate,
        Field(description='Canonical demographic predicate actually applied by the seller.'),
    ]
    equivalent: Annotated[
        Literal[True],
        Field(
            description='Always true for a stored package. requested and applied MUST denote exactly the same set, including unknown-age membership; sellers reject non-equivalent requests instead of storing an alternative.'
        ),
    ]
    execution: Execution | Execution1 | Execution2
    applied_bases: Annotated[
        list[age_determination_basis.AgeDeterminationBasis] | None,
        Field(
            description='Effective user-level determination bases configured for this package after intersecting buyer accepted_bases, product supported_bases, and age_restriction. This is an auditable configuration readback, not proof that every impression used every listed basis.',
            min_length=1,
        ),
    ] = None
    applied_verification_methods: Annotated[
        list[age_verification_method.AgeVerificationMethod] | None,
        Field(
            description='Effective verification methods when applied_bases contains verified. A method name does not establish that a particular proof or claim was valid; runtime verification and claim entailment remain required.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 applied : DemographicPredicate
var applied_bases : list[AgeDeterminationBasis] | None
var applied_verification_methods : list[AgeVerificationMethod] | None
var equivalent : Literal[True]
var execution : Execution | Execution1 | Execution2
var ext : ExtensionObject | None
var model_config
var requested : DemographicTargetingIntent

Inherited members

class Deployment1 (**data: Any)
Expand source code
class Deployment1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['platform'],
        Field(description='Discriminator indicating this is a platform-based deployment'),
    ] = 'platform'
    platform: Annotated[str, Field(description='Platform identifier for DSPs')]
    account: Annotated[str | None, Field(description='Account identifier if applicable')] = None
    is_live: Annotated[
        StrictBool, Field(description='Whether signal is currently active on this deployment')
    ]
    activation_key: Annotated[
        activation_key_1.ActivationKey | None,
        Field(
            description='The key to use for targeting. Only present if is_live=true AND requester has access to this deployment.'
        ),
    ] = None
    estimated_activation_duration_minutes: Annotated[
        StrictFloat | None,
        Field(
            description='Estimated time to activate if not live, or to complete activation if in progress',
            ge=0.0,
        ),
    ] = None
    deployed_at: Annotated[
        AwareDatetime | None,
        Field(description='Timestamp when activation completed (if is_live=true)'),
    ] = 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 account : str | None
var activation_key : ActivationKey1 | ActivationKey2 | None
var deployed_at : pydantic.types.AwareDatetime | None
var estimated_activation_duration_minutes : float | None
var is_live : bool
var model_config
var platform : str
var type : Literal['platform']

Inherited members

class Deployment2 (**data: Any)
Expand source code
class Deployment2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['agent'],
        Field(description='Discriminator indicating this is an agent URL-based deployment'),
    ] = 'agent'
    agent_url: Annotated[AnyUrl, Field(description='URL identifying the deployment agent')]
    account: Annotated[str | None, Field(description='Account identifier if applicable')] = None
    is_live: Annotated[
        StrictBool, Field(description='Whether signal is currently active on this deployment')
    ]
    activation_key: Annotated[
        activation_key_1.ActivationKey | None,
        Field(
            description='The key to use for targeting. Only present if is_live=true AND requester has access to this deployment.'
        ),
    ] = None
    estimated_activation_duration_minutes: Annotated[
        StrictFloat | None,
        Field(
            description='Estimated time to activate if not live, or to complete activation if in progress',
            ge=0.0,
        ),
    ] = None
    deployed_at: Annotated[
        AwareDatetime | None,
        Field(description='Timestamp when activation completed (if is_live=true)'),
    ] = 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 account : str | None
var activation_key : ActivationKey1 | ActivationKey2 | None
var agent_url : pydantic.networks.AnyUrl
var deployed_at : pydantic.types.AwareDatetime | None
var estimated_activation_duration_minutes : float | None
var is_live : bool
var model_config
var type : Literal['agent']

Inherited members

class DerivativeOf (**data: Any)
Expand source code
class DerivativeOf(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    installment_id: Annotated[
        str, Field(description='The source installment this content is derived from')
    ]
    type: Annotated[
        derivative_type.DerivativeType, Field(description='What kind of derivative content this is')
    ]

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 installment_id : str
var model_config
var type : DerivativeType

Inherited members

class Destination1 (**data: Any)
Expand source code
class Destination1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['platform'],
        Field(description='Discriminator indicating this is a platform-based deployment'),
    ] = 'platform'
    platform: Annotated[
        str,
        Field(description="Platform identifier for DSPs (e.g., 'the-trade-desk', 'amazon-dsp')"),
    ]
    account: Annotated[
        str | None, Field(description='Optional account identifier on the platform')
    ] = 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 account : str | None
var model_config
var platform : str
var type : Literal['platform']

Inherited members

class Destination2 (**data: Any)
Expand source code
class Destination2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        Literal['agent'],
        Field(description='Discriminator indicating this is an agent URL-based deployment'),
    ] = 'agent'
    agent_url: Annotated[
        AnyUrl, Field(description='URL identifying the deployment agent (for sales agents, etc.)')
    ]
    account: Annotated[
        str | None, Field(description='Optional account identifier on the agent')
    ] = 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 account : str | None
var agent_url : pydantic.networks.AnyUrl
var model_config
var type : Literal['agent']

Inherited members

class DestinationItem (**data: Any)
Expand source code
class DestinationItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    destination_id: Annotated[str, Field(description='Unique identifier for this destination.')]
    name: Annotated[
        str, Field(description="Destination name (e.g., 'Barcelona', 'Bali', 'Swiss Alps').")
    ]
    description: Annotated[
        str | None,
        Field(description='Destination description highlighting attractions and appeal.'),
    ] = None
    city: Annotated[str | None, Field(description='City name, if applicable.')] = None
    region: Annotated[str | None, Field(description='State, province, or region name.')] = None
    country: Annotated[
        str | None, Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = None
    location: Annotated[
        Location | None, Field(description='Geographic coordinates of the destination.')
    ] = None
    destination_type: Annotated[
        DestinationType | None, Field(description='Destination category.')
    ] = None
    price: Annotated[
        price_1.Price | None, Field(description='Starting price for a trip to this destination.')
    ] = None
    image_url: Annotated[AnyUrl | None, Field(description='Destination hero image URL.')] = None
    url: Annotated[AnyUrl | None, Field(description='Destination landing page or booking URL.')] = (
        None
    )
    rating: Annotated[
        StrictFloat | None, Field(description='Destination rating (1–5).', ge=1.0, le=5.0)
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering (e.g., 'family', 'romantic', 'solo', 'winter-sun').",
            min_length=1,
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this destination. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (destination hero), 'images_vertical' (9:16 for Snap, Stories), 'images_square' (1:1). Enables formats to declare typed image requirements that map unambiguously to the right asset regardless of platform.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 assets : list[OfferingAssetGroup] | None
var city : str | None
var country : str | None
var description : str | None
var destination_id : str
var destination_type : DestinationType | None
var ext : ExtensionObject | None
var image_url : pydantic.networks.AnyUrl | None
var location : Location | None
var model_config
var name : str
var price : Price | None
var rating : float | None
var region : str | None
var tags : list[str] | None
var url : pydantic.networks.AnyUrl | None

Inherited members

class DestinationMode (*args, **kwds)
Expand source code
class DestinationMode(StrEnum):
    provision = 'provision'
    existing = 'existing'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var existing
var provision
class DestinationRef (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class DestinationRef(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 255, 'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class DestinationType (*args, **kwds)
Expand source code
class DestinationType(StrEnum):
    beach = 'beach'
    mountain = 'mountain'
    urban = 'urban'
    cultural = 'cultural'
    adventure = 'adventure'
    wellness = 'wellness'
    cruise = 'cruise'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var adventure
var beach
var cruise
var cultural
var mountain
var urban
var wellness
class Detail (**data: Any)
Expand source code
class Detail(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    score: Annotated[
        StrictFloat,
        Field(
            description='Seller-defined quality score. Scale varies by seller — only compare within the same seller.',
            ge=0.0,
        ),
    ]
    max_score: Annotated[
        StrictFloat, Field(description="Maximum possible score on this seller's scale.", ge=1.0)
    ]
    label: Annotated[
        str | None,
        Field(
            description="Seller's name for this score (e.g., 'Event Quality Score', 'Event Match Quality')."
        ),
    ] = 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 label : str | None
var max_score : float
var model_config
var score : float

Inherited members

class Details (**data: Any)
Expand source code
class Details(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    protocol: Annotated[
        adcp_protocol.AdcpProtocol | None, Field(description='AdCP protocol where error occurred')
    ] = None
    operation: Annotated[str | None, Field(description='Specific operation that failed')] = None
    specific_context: Annotated[
        dict[str, Any] | None, Field(description='Domain-specific error context')
    ] = 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 model_config
var operation : str | None
var protocol : AdcpProtocol | None
var specific_context : dict[str, typing.Any] | None

Inherited members

class DevicePlatformForecastDimension (**data: Any)
Expand source code
class DevicePlatformForecastDimension(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Annotated[
        Literal['device_platform'], Field(description='Dimension family discriminator.')
    ] = 'device_platform'
    device_platform: Annotated[
        device_platform_1.DevicePlatform,
        Field(description='Operating system or platform for this forecast row.'),
    ]

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 device_platform : DevicePlatform
var kind : Literal['device_platform']
var model_config

Inherited members

class DeviceTypeForecastDimension (**data: Any)
Expand source code
class DeviceTypeForecastDimension(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Annotated[Literal['device_type'], Field(description='Dimension family discriminator.')] = 'device_type'
    device_type: Annotated[
        device_type_1.DeviceType, Field(description='Device form factor for this forecast row.')
    ]

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 device_type : DeviceType
var kind : Literal['device_type']
var model_config

Inherited members

class DiagnosticIssue (**data: Any)
Expand source code
class DiagnosticIssue(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    severity: Annotated[
        Severity,
        Field(
            description="'error': blocks optimization until resolved. 'warning': optimization works but effectiveness is reduced. 'info': suggestion for improvement."
        ),
    ]
    message: Annotated[
        str,
        Field(description='Human/agent-readable description of the issue and how to resolve it.'),
    ]

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 message : str
var model_config
var severity : Severity

Inherited members

class DigitalSourceType (*args, **kwds)
Expand source code
class DigitalSourceType(StrEnum):
    digital_capture = 'digital_capture'
    digital_creation = 'digital_creation'
    trained_algorithmic_media = 'trained_algorithmic_media'
    composite_with_trained_algorithmic_media = 'composite_with_trained_algorithmic_media'
    algorithmic_media = 'algorithmic_media'
    composite_capture = 'composite_capture'
    composite_synthetic = 'composite_synthetic'
    human_edits = 'human_edits'
    data_driven_media = 'data_driven_media'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var algorithmic_media
var composite_capture
var composite_synthetic
var composite_with_trained_algorithmic_media
var data_driven_media
var digital_capture
var digital_creation
var human_edits
var trained_algorithmic_media
class Dimensions (**data: Any)
Expand source code
class Dimensions(AdCPBaseModel):
    width: Annotated[
        StrictFloat | None,
        Field(description='Fixed width. Interpretation depends on unit (default: pixels).', gt=0.0),
    ] = None
    height: Annotated[
        StrictFloat | None,
        Field(
            description='Fixed height. Interpretation depends on unit (default: pixels).', gt=0.0
        ),
    ] = None
    min_width: Annotated[
        StrictFloat | None, Field(description='Minimum width for responsive renders', gt=0.0)
    ] = None
    min_height: Annotated[
        StrictFloat | None, Field(description='Minimum height for responsive renders', gt=0.0)
    ] = None
    max_width: Annotated[
        StrictFloat | None, Field(description='Maximum width for responsive renders', gt=0.0)
    ] = None
    max_height: Annotated[
        StrictFloat | None, Field(description='Maximum height for responsive renders', gt=0.0)
    ] = None
    unit: Annotated[
        dimension_unit.DimensionUnit | None,
        Field(
            description="Unit of measurement for width/height values. Defaults to 'px' when absent. Print formats use 'inches' or 'cm'."
        ),
    ] = None
    responsive: Annotated[
        Responsive | None, Field(description='Indicates which dimensions are responsive/fluid')
    ] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description="Fixed aspect ratio constraint (e.g., '16:9', '4:3', '1:1', '1.91:1')",
            pattern='^\\d+(\\.\\d+)?:\\d+(\\.\\d+)?$',
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var aspect_ratio : str | None
var height : float | None
var max_height : float | None
var max_width : float | None
var min_height : float | None
var min_width : float | None
var model_config
var responsive : Responsive | None
var unit : DimensionUnit | None
var width : float | None

Inherited members

class Dimensions1 (**data: Any)
Expand source code
class Dimensions1(Dimensions):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class DisclosureCapability (**data: Any)
Expand source code
class DisclosureCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    position: Annotated[
        disclosure_position.DisclosurePosition, Field(description='The disclosure position')
    ]
    persistence: Annotated[
        list[disclosure_persistence.DisclosurePersistence],
        Field(description='Persistence modes this position supports', 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 model_config
var persistence : list[DisclosurePersistence]
var position : DisclosurePosition

Inherited members

class DisclosurePersistence (*args, **kwds)
Expand source code
class DisclosurePersistence(StrEnum):
    continuous = 'continuous'
    initial = 'initial'
    flexible = 'flexible'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var continuous
var flexible
var initial
class DisclosurePosition (*args, **kwds)
Expand source code
class DisclosurePosition(StrEnum):
    prominent = 'prominent'
    footer = 'footer'
    audio = 'audio'
    subtitle = 'subtitle'
    overlay = 'overlay'
    end_card = 'end_card'
    pre_roll = 'pre_roll'
    companion = 'companion'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var audio
var companion
var end_card
var footer
var overlay
var pre_roll
var prominent
var subtitle
class DiscriminatorItem (**data: Any)
Expand source code
class DiscriminatorItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    property_name: Annotated[
        str,
        Field(
            description='Discriminator property name (e.g., `type`, `value_type`). Aligns with OpenAPI 3.x `discriminator.propertyName`.'
        ),
    ]
    value: Annotated[
        str | StrictFloat | StrictBool | None,
        Field(
            description="Value the caller sent at `property_name`. Typically a string for const-discriminated unions; numeric/boolean/null permitted. Object and array values are forbidden — const discriminators are scalars, and emitting a structured value would conflate 'caller sent a complex shape' with 'validator inferred from a structural match'."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var property_name : str
var value : str | float | bool | None

Inherited members

class DisplayTagAsset1 (**data: Any)
Expand source code
class DisplayTagAsset1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['display_tag'],
        Field(
            description='Discriminator identifying an atomic third-party display-tag representation.'
        ),
    ] = 'display_tag'
    macro_declarations: Annotated[
        list[MacroDeclaration2] | None,
        Field(
            description='Exact macro tokens present anywhere in this representation. Tokens remain byte-preserved until the resolver named by each declaration substitutes them.',
            min_length=1,
        ),
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this asset, overriding manifest-level provenance.'
        ),
    ] = None
    delivery_type: Literal['tag_url'] = 'tag_url'
    url: Annotated[
        MacroBearingUrl,
        Field(
            description='Ad-request URL invoked at impression time. It is equivalent to the backward-compatible `url` asset with `url_type: "ad_request"`.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['display_tag']
var delivery_type : Literal['tag_url']
var macro_declarations : list[MacroDeclaration2] | None
var model_config
var provenance : Provenance | None
var url : str | MacroBearingUrl1 | MacroBearingUrl2

Inherited members

class DisplayTagAsset2 (**data: Any)
Expand source code
class DisplayTagAsset2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['display_tag'],
        Field(
            description='Discriminator identifying an atomic third-party display-tag representation.'
        ),
    ] = 'display_tag'
    macro_declarations: Annotated[
        list[MacroDeclaration3] | None,
        Field(
            description='Exact macro tokens present anywhere in this representation. Tokens remain byte-preserved until the resolver named by each declaration substitutes them.',
            min_length=1,
        ),
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this asset, overriding manifest-level provenance.'
        ),
    ] = None
    delivery_type: Literal['inline_markup'] = 'inline_markup'
    markup_type: Annotated[
        MarkupType, Field(description='How the destination traffics the byte-preserved markup.')
    ]
    markup: Annotated[
        str,
        Field(
            description='Exact third-party tag markup. Receivers MUST preserve its bytes and MUST NOT reinterpret it as a seller-hosted HTML5 bundle.',
            max_length=1048576,
            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_type : Literal['display_tag']
var delivery_type : Literal['inline_markup']
var macro_declarations : list[MacroDeclaration3] | None
var markup : str
var markup_type : MarkupType
var model_config
var provenance : Provenance | None

Inherited members

class DisplayTagAsset3 (**data: Any)
Expand source code
class DisplayTagAsset3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['display_tag'],
        Field(
            description='Discriminator identifying an atomic third-party display-tag representation.'
        ),
    ] = 'display_tag'
    macro_declarations: Annotated[
        list[MacroDeclaration4] | None,
        Field(
            description='Exact macro tokens present anywhere in this representation. Tokens remain byte-preserved until the resolver named by each declaration substitutes them.',
            min_length=1,
        ),
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this asset, overriding manifest-level provenance.'
        ),
    ] = None
    delivery_type: Literal['paired_redirect'] = 'paired_redirect'
    ad_request_url: Annotated[
        MacroBearingUrl,
        Field(
            description='Image or ad-request URL entered into the destination ad server. This field deliberately accepts byte-preserved vendor tokens that are not RFC 6570 URI templates.'
        ),
    ]
    clickthrough_url: Annotated[
        MacroBearingUrl,
        Field(
            description='Click-through URL paired with `ad_request_url`. This field deliberately accepts byte-preserved vendor tokens that are not RFC 6570 URI templates. The pair MUST NOT be split, mixed, or revised independently.'
        ),
    ]

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 ad_request_url : str | MacroBearingUrl1 | MacroBearingUrl2
var asset_type : Literal['display_tag']
var clickthrough_url : str | MacroBearingUrl1 | MacroBearingUrl2
var delivery_type : Literal['paired_redirect']
var macro_declarations : list[MacroDeclaration4] | None
var model_config
var provenance : Provenance | None

Inherited members

class DisplayTagAsset4 (**data: Any)
Expand source code
class DisplayTagAsset4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['display_tag'],
        Field(
            description='Discriminator identifying an atomic third-party display-tag representation.'
        ),
    ] = 'display_tag'
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='Exact macro tokens present anywhere in this representation. Tokens remain byte-preserved until the resolver named by each declaration substitutes them.',
            min_length=1,
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overriding manifest-level provenance.'
        ),
    ] = None
    delivery_type: Literal['tag_url'] = 'tag_url'
    url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='Ad-request URL invoked at impression time. It is equivalent to the backward-compatible `url` asset with `url_type: "ad_request"`.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['display_tag']
var delivery_type : Literal['tag_url']
var macro_declarations : list[MacroDeclaration] | None
var model_config
var provenance : Provenance | None
var url : str | MacroBearingUrl3 | MacroBearingUrl4

Inherited members

class DisplayTagAsset5 (**data: Any)
Expand source code
class DisplayTagAsset5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['display_tag'],
        Field(
            description='Discriminator identifying an atomic third-party display-tag representation.'
        ),
    ] = 'display_tag'
    macro_declarations: Annotated[
        list[MacroDeclaration15] | None,
        Field(
            description='Exact macro tokens present anywhere in this representation. Tokens remain byte-preserved until the resolver named by each declaration substitutes them.',
            min_length=1,
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overriding manifest-level provenance.'
        ),
    ] = None
    delivery_type: Literal['inline_markup'] = 'inline_markup'
    markup_type: Annotated[
        MarkupType, Field(description='How the destination traffics the byte-preserved markup.')
    ]
    markup: Annotated[
        str,
        Field(
            description='Exact third-party tag markup. Receivers MUST preserve its bytes and MUST NOT reinterpret it as a seller-hosted HTML5 bundle.',
            max_length=1048576,
            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_type : Literal['display_tag']
var delivery_type : Literal['inline_markup']
var macro_declarations : list[MacroDeclaration15] | None
var markup : str
var markup_type : MarkupType
var model_config
var provenance : Provenance | None

Inherited members

class DisplayTagAsset6 (**data: Any)
Expand source code
class DisplayTagAsset6(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['display_tag'],
        Field(
            description='Discriminator identifying an atomic third-party display-tag representation.'
        ),
    ] = 'display_tag'
    macro_declarations: Annotated[
        list[MacroDeclaration16] | None,
        Field(
            description='Exact macro tokens present anywhere in this representation. Tokens remain byte-preserved until the resolver named by each declaration substitutes them.',
            min_length=1,
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overriding manifest-level provenance.'
        ),
    ] = None
    delivery_type: Literal['paired_redirect'] = 'paired_redirect'
    ad_request_url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='Image or ad-request URL entered into the destination ad server. This field deliberately accepts byte-preserved vendor tokens that are not RFC 6570 URI templates.'
        ),
    ]
    clickthrough_url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='Click-through URL paired with `ad_request_url`. This field deliberately accepts byte-preserved vendor tokens that are not RFC 6570 URI templates. The pair MUST NOT be split, mixed, or revised independently.'
        ),
    ]

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 ad_request_url : str | MacroBearingUrl3 | MacroBearingUrl4
var asset_type : Literal['display_tag']
var clickthrough_url : str | MacroBearingUrl3 | MacroBearingUrl4
var delivery_type : Literal['paired_redirect']
var macro_declarations : list[MacroDeclaration16] | None
var model_config
var provenance : Provenance | None

Inherited members

class DomainBreakdown (**data: Any)
Expand source code
class DomainBreakdown(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    media_buy: Annotated[
        SchemaInt | None,
        Field(alias='media-buy', description='Number of media-buy tasks in results', ge=0),
    ] = None
    signals: Annotated[
        SchemaInt | None, Field(description='Number of signals tasks in results', ge=0)
    ] = None
    creative: Annotated[
        SchemaInt | None, Field(description='Number of creative tasks in results', 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

Class variables

var creative : int | None
var media_buy : int | None
var model_config
var signals : int | None

Inherited members

class DoohMetrics (**data: Any)
Expand source code
class DoohMetrics(DoohMetrics1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class DoohMetrics1 (**data: Any)
Expand source code
class DoohMetrics1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    loop_plays: Annotated[
        SchemaInt | None, Field(description='Number of times ad played in rotation', ge=0)
    ] = None
    screens_used: Annotated[
        SchemaInt | None, Field(description='Number of unique screens displaying the ad', ge=0)
    ] = None
    screen_time_seconds: Annotated[
        SchemaInt | None, Field(description='Total display time in seconds', ge=0)
    ] = None
    sov_achieved: Annotated[
        StrictFloat | None,
        Field(
            description='Actual share of voice delivered on a 0.0-1.0 scale. To compare this achieved value with the selected flat-rate DOOH parameters.sov_percentage, multiply sov_achieved by 100. Share is time-weighted: the sum of the delivered segment durations divided by the full loop duration. On equal-duration loops this equals the slot-count ratio. See also ooh_metrics.share_of_voice_contracted, which uses the same 0.0-1.0 scale.',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    calculation_notes: Annotated[
        str | None,
        Field(
            description="Per-row supplementary methodology notes for DOOH impression calculation (e.g., 'rotation-based; 6-second slot weighted by 70% audience overlap'). Free-form prose for context that doesn't fit the structured measurement-vendor surface. Canonical methodology declarations belong on the measurement vendor's `get_adcp_capabilities.measurement.metrics[]` block where they're discoverable once and inherited across delivery rows; this field is for row-specific context (a particular daypart's calculation, a venue-mix exception) rather than the seller's general methodology."
        ),
    ] = None
    venue_breakdown: Annotated[
        list[VenueBreakdownItem] | None, Field(description='Per-venue performance breakdown')
    ] = 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 calculation_notes : str | None
var loop_plays : int | None
var model_config
var screen_time_seconds : int | None
var screens_used : int | None
var sov_achieved : float | None
var venue_breakdown : list[VenueBreakdownItem] | None

Inherited members

class DownstreamConnectionRequirement (**data: Any)
Expand source code
class DownstreamConnectionRequirement(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    provider: Annotated[
        str | None,
        Field(
            description='Stable provider or platform namespace, preferably lowercase. Examples: `social.example`, `shortvideo.example`, or a seller-defined namespace. Omit only when the requirement is provider-agnostic, or when an `authorization_url` fully routes the human to the correct provider-specific connection flow.'
        ),
    ] = None
    connection_type: Annotated[
        ConnectionType,
        Field(
            description='Kind of downstream connection required. `advertiser_account` is the platform account used to buy/manage ads. `publisher_identity` is the creator, page, channel, organization, or profile that owns source posts. `post_authorization` is a post-scoped grant when the platform authorizes individual posts instead of, or in addition to, the owning identity.'
        ),
    ]
    required_for: Annotated[
        list[RequiredForItem] | None,
        Field(
            description='Concrete AdCP protocol operation names that require this downstream connection. Sellers SHOULD include this in product declarations when the requirement is known ahead of time, and in AUTHORIZATION_REQUIRED details when it explains the failed operation. Prefer specific operation names such as `list_creatives`, `sync_creatives`, `create_media_buy`, `get_media_buy_delivery`, or `get_creative_delivery` over broad category labels such as `reporting`.'
        ),
    ] = None
    scope: Annotated[Scope | None, Field(description='Granularity of the downstream grant.')] = None
    status: Annotated[
        Status | None,
        Field(
            description='Current seller-observed state for this downstream connection when known. Product declarations MAY omit status or use `unknown`; AUTHORIZATION_REQUIRED details SHOULD use `missing`, `expired`, or `revoked` for the connection that blocked the call.'
        ),
    ] = None
    connection_id: Annotated[
        str | None,
        Field(
            description='Seller-defined identifier for an already-created downstream connection. Omit when no connection exists yet or when exposing it would leak platform/account state.'
        ),
    ] = None
    resource_ref: Annotated[
        ResourceRef | None,
        Field(
            description='Optional opaque provider-native resource hint, such as a platform account id, profile URL, handle, channel id, post id, or post URL. This is a hint for routing authorization, not proof that authorization exists.'
        ),
    ] = None
    authorization_url: Annotated[
        AnyUrl | None,
        Field(
            description='Seller-hosted or provider-hosted URL where a human can complete or restore this downstream connection.'
        ),
    ] = None
    authorization_instructions: Annotated[
        str | None,
        Field(
            description='Human-readable instructions for completing or restoring this downstream connection.'
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(description='Expiration time for the downstream grant, when known.'),
    ] = 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 authorization_instructions : str | None
var authorization_url : pydantic.networks.AnyUrl | None
var connection_id : str | None
var connection_type : ConnectionType
var expires_at : pydantic.types.AwareDatetime | None
var model_config
var provider : str | None
var required_for : list[RequiredForItem] | None
var resource_ref : ResourceRef | None
var scope : Scope | None
var status : Status | None

Inherited members

class Duration (**data: Any)
Expand source code
class Duration(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    interval: Annotated[
        SchemaInt,
        Field(description="Number of time units. Must be 1 when unit is 'campaign'.", ge=1),
    ]
    unit: Annotated[
        Unit,
        Field(
            description="Time unit. 'seconds' for sub-minute precision. 'campaign' spans the full campaign flight."
        ),
    ]

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 interval : int
var model_config
var unit : Unit

Inherited members

class EducationItem (**data: Any)
Expand source code
class EducationItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    program_id: Annotated[str, Field(description='Unique identifier for this program or course.')]
    name: Annotated[
        str,
        Field(
            description="Program or course name (e.g., 'MSc Computer Science', 'Digital Marketing Certificate')."
        ),
    ]
    school: Annotated[str, Field(description='Institution or provider name.')]
    description: Annotated[
        str | None,
        Field(description='Program description including curriculum highlights and outcomes.'),
    ] = None
    subject: Annotated[
        str | None,
        Field(
            description="Subject area or field of study (e.g., 'computer-science', 'business', 'healthcare')."
        ),
    ] = None
    degree_type: Annotated[DegreeType | None, Field(description='Type of credential awarded.')] = (
        None
    )
    level: Annotated[Level | None, Field(description='Difficulty or prerequisite level.')] = None
    price: Annotated[price_1.Price | None, Field(description='Tuition or course fee.')] = None
    duration: Annotated[
        str | None,
        Field(
            description="Program duration as a human-readable string (e.g., '4 weeks', '2 years', '6 months')."
        ),
    ] = None
    start_date: Annotated[
        date | None, Field(description='Next available start date (ISO 8601 date).')
    ] = None
    language: Annotated[
        str | None, Field(description="Language of instruction (e.g., 'en', 'nl', 'es').")
    ] = None
    modality: Annotated[Modality | None, Field(description='Delivery format.')] = None
    location: Annotated[
        str | None,
        Field(
            description="Campus or instruction location (e.g., 'Amsterdam, NL'). Omit for fully online programs."
        ),
    ] = None
    image_url: Annotated[AnyUrl | None, Field(description='Program or institution image URL.')] = (
        None
    )
    url: Annotated[AnyUrl | None, Field(description='Program landing page or enrollment URL.')] = (
        None
    )
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering (e.g., 'stem', 'scholarship-available', 'evening-classes').",
            min_length=1,
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this program. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (campus/program hero), 'images_vertical' (9:16 for Stories), 'logo' (institution logo). Enables formats to declare typed image requirements that map unambiguously to the right asset regardless of platform.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 assets : list[OfferingAssetGroup] | None
var degree_type : DegreeType | None
var description : str | None
var duration : str | None
var ext : ExtensionObject | None
var image_url : pydantic.networks.AnyUrl | None
var language : str | None
var level : Level | None
var location : str | None
var modality : Modality | None
var model_config
var name : str
var price : Price | None
var program_id : str
var school : str
var start_date : datetime.date | None
var subject : str | None
var tags : list[str] | None
var url : pydantic.networks.AnyUrl | None

Inherited members

class Effect1 (*args, **kwds)
Expand source code
class Effect1(StrEnum):
    preserved = 'preserved'
    revalidation_required = 'revalidation_required'
    revoke_and_regrant = 'revoke_and_regrant'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var preserved
var revalidation_required
var revoke_and_regrant
class EmbeddedCredential (**data: Any)
Expand source code
class EmbeddedCredential(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    format: Annotated[
        AnyUrl,
        Field(
            description='Open, absolute URI identifying the credential/proof format. AdCP does not impose a universal issuer payload schema.'
        ),
    ]
    value: Annotated[
        dict[str, Any] | str,
        Field(
            description='Credential encoded as a JSON object or a compact string, according to format.',
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var format : pydantic.networks.AnyUrl
var model_config
var value : dict[str, typing.Any] | str

Inherited members

class EmbeddedProvenanceMethod (*args, **kwds)
Expand source code
class EmbeddedProvenanceMethod(StrEnum):
    manifest_wrapper = 'manifest_wrapper'
    provenance_markers = 'provenance_markers'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var manifest_wrapper
var provenance_markers
class EmploymentType (*args, **kwds)
Expand source code
class EmploymentType(StrEnum):
    full_time = 'full_time'
    part_time = 'part_time'
    contract = 'contract'
    temporary = 'temporary'
    internship = 'internship'
    freelance = 'freelance'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var contract
var freelance
var full_time
var internship
var part_time
var temporary
class EmptyReport (**data: Any)
Expand source code
class EmptyReport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: Annotated[str, Field(max_length=128, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,128}$')]
    purpose: Literal['empty_report'] = 'empty_report'
    input_rows: Annotated[list[Any], Field(max_length=0)]
    canonical_utf8_base64: Annotated[
        Literal['W10='], Field(description='Base64 of the exact UTF-8 bytes for [].')
    ] = 'W10='
    sha256: Literal['4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945'] = '4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945'

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 canonical_utf8_base64 : Literal['W10=']
var input_rows : list[typing.Any]
var model_config
var name : str
var purpose : Literal['empty_report']
var sha256 : Literal['4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945']

Inherited members

class EstimationBasis (*args, **kwds)
Expand source code
class EstimationBasis(StrEnum):
    currency_measured = 'currency_measured'
    seller_modeled = 'seller_modeled'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var currency_measured
var seller_modeled
class EvalBudget (**data: Any)
Expand source code
class EvalBudget(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_calls: Annotated[
        SchemaInt | None,
        Field(description='Soft cap on the number of judge calls the evaluator should make.', ge=1),
    ] = None
    max_seconds: Annotated[
        StrictFloat | None,
        Field(description='Soft cap on wall-clock seconds the evaluation should consume.', ge=0.0),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var max_calls : int | None
var max_seconds : float | None
var model_config

Inherited members

class EvaluatorSpec1 (**data: Any)
Expand source code
class EvaluatorSpec1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    feature_requirement: Annotated[
        list[feature_requirement_1.FeatureRequirement] | None,
        Field(
            description='Optional hard GATE over creative-feature values — the predicates a leaf MUST satisfy for the producing agent to recommend/return it. Reuses the feature-requirement shape (min_value/max_value for quantitative features like creative_quality_score, allowed_values for binary/categorical) — the same predicate vocabulary that gates property/audience filters, which its own schema names as an intended creative-gate reuse. A leaf that fails any predicate is DROPPED from the agent\'s best_of_n survivors before ranking — this is internal pruning of which leaves the agent recommends, not an AdCP-layer block of an already-produced billable leaf (what is produced/billed is governed by max_variants/max_creatives/max_spend). Distinct from `rank_by`: the gate is a pass/fail predicate (drop on fail), `rank_by` is an ordering over survivors. Each predicate\'s `if_not_covered` (exclude|include, default exclude) is the fail-open knob when the source cannot measure that feature. A pass/warn/fail verdict is expressed as a categorical string feature value gated via `allowed_values` (e.g. ["pass"] or ["pass","warn"]) — the buyer\'s predicate decides whether warn passes; the verdict is derived, never stored on creative-feature-result. Omit to leave evaluation advisory (no leaf is dropped).',
            min_length=1,
        ),
    ] = None
    rank_by: Annotated[
        list[RankByItem] | None,
        Field(
            description='Optional RANK ordering over creative-feature values — an ordered list (most significant first) the agent uses to order the gate survivors into recommended/rank. An explicit {feature_id, direction} ordering rather than the feature-requirement predicate (which has no sort direction): the gate decides pass/fail, rank_by decides better/worse. Soft preference, never a gate: leaves are not dropped by rank_by, they are only ordered. Omit to let the evaluator/seller choose the ordering.',
            min_length=1,
        ),
    ] = None
    feature_agent: Annotated[
        FeatureAgent | None,
        Field(
            description="Optional buyer-attached pointer to a get_creative_features-capable creative-feature / governance agent the producing agent calls to evaluate each leaf (the gate's SOURCE of feature values). This is the buyer-represents → seller-calls pattern #5280 established for provenance, generalized to the evaluator gate: the buyer REPRESENTS which agent it used, but the seller is the verifier-of-record and decides which agent it actually calls. `agent_url` MUST appear (canonicalized per /docs/reference/url-canonicalization) in the seller's `creative_policy.accepted_verifiers[].agent_url`; an off-list agent is rejected with `EVALUATOR_AGENT_NOT_ACCEPTED` (mirrors PROVENANCE_VERIFIER_NOT_ACCEPTED) before any outbound call. The outbound evaluator call authenticates on the transport; this pointer MUST NOT carry API keys, bearer tokens, client secrets, authorization values, JWKs, JWKS documents, or JWKS URIs. Reuses the same allowlist mechanism — no new allowlist is introduced. Distinct from the `agent_url` oneOf form, which names the evaluator's source directly; `feature_agent` attaches the gate's measurement source alongside any of the three forms."
        ),
    ] = None
    eval_budget: Annotated[
        EvalBudget | None,
        Field(
            description='Optional soft ceiling on evaluation effort. Advisory in v1 with no billing coupling. Well-known soft fields max_calls / max_seconds; open for evaluator-specific knobs.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None
    exemplars: Annotated[
        Exemplars,
        Field(
            description='Pass/fail examples that calibrate the single prediction feature (e.g. `predicted_performance` in [0,1]) the evaluator returns in eval.features[]. Artifact-based, mirroring content-standards.json calibration_exemplars.'
        ),
    ]

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 eval_budget : EvalBudget | None
var exemplars : Exemplars
var ext : ExtensionObject | None
var feature_agent : FeatureAgent | None
var feature_requirement : list[FeatureRequirement] | None
var model_config
var rank_by : list[RankByItem] | None

Inherited members

class EvaluatorSpec2 (**data: Any)
Expand source code
class EvaluatorSpec2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    feature_requirement: Annotated[
        list[feature_requirement_1.FeatureRequirement] | None,
        Field(
            description='Optional hard GATE over creative-feature values — the predicates a leaf MUST satisfy for the producing agent to recommend/return it. Reuses the feature-requirement shape (min_value/max_value for quantitative features like creative_quality_score, allowed_values for binary/categorical) — the same predicate vocabulary that gates property/audience filters, which its own schema names as an intended creative-gate reuse. A leaf that fails any predicate is DROPPED from the agent\'s best_of_n survivors before ranking — this is internal pruning of which leaves the agent recommends, not an AdCP-layer block of an already-produced billable leaf (what is produced/billed is governed by max_variants/max_creatives/max_spend). Distinct from `rank_by`: the gate is a pass/fail predicate (drop on fail), `rank_by` is an ordering over survivors. Each predicate\'s `if_not_covered` (exclude|include, default exclude) is the fail-open knob when the source cannot measure that feature. A pass/warn/fail verdict is expressed as a categorical string feature value gated via `allowed_values` (e.g. ["pass"] or ["pass","warn"]) — the buyer\'s predicate decides whether warn passes; the verdict is derived, never stored on creative-feature-result. Omit to leave evaluation advisory (no leaf is dropped).',
            min_length=1,
        ),
    ] = None
    rank_by: Annotated[
        list[RankByItem1] | None,
        Field(
            description='Optional RANK ordering over creative-feature values — an ordered list (most significant first) the agent uses to order the gate survivors into recommended/rank. An explicit {feature_id, direction} ordering rather than the feature-requirement predicate (which has no sort direction): the gate decides pass/fail, rank_by decides better/worse. Soft preference, never a gate: leaves are not dropped by rank_by, they are only ordered. Omit to let the evaluator/seller choose the ordering.',
            min_length=1,
        ),
    ] = None
    feature_agent: Annotated[
        FeatureAgent | None,
        Field(
            description="Optional buyer-attached pointer to a get_creative_features-capable creative-feature / governance agent the producing agent calls to evaluate each leaf (the gate's SOURCE of feature values). This is the buyer-represents → seller-calls pattern #5280 established for provenance, generalized to the evaluator gate: the buyer REPRESENTS which agent it used, but the seller is the verifier-of-record and decides which agent it actually calls. `agent_url` MUST appear (canonicalized per /docs/reference/url-canonicalization) in the seller's `creative_policy.accepted_verifiers[].agent_url`; an off-list agent is rejected with `EVALUATOR_AGENT_NOT_ACCEPTED` (mirrors PROVENANCE_VERIFIER_NOT_ACCEPTED) before any outbound call. The outbound evaluator call authenticates on the transport; this pointer MUST NOT carry API keys, bearer tokens, client secrets, authorization values, JWKs, JWKS documents, or JWKS URIs. Reuses the same allowlist mechanism — no new allowlist is introduced. Distinct from the `agent_url` oneOf form, which names the evaluator's source directly; `feature_agent` attaches the gate's measurement source alongside any of the three forms."
        ),
    ] = None
    eval_budget: Annotated[
        EvalBudget | None,
        Field(
            description='Optional soft ceiling on evaluation effort. Advisory in v1 with no billing coupling. Well-known soft fields max_calls / max_seconds; open for evaluator-specific knobs.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None
    evaluator_id: Annotated[
        str,
        Field(
            description='Account-scoped house evaluator preset selected by the buyer. This id is pre-provisioned/account-arranged, not discovered from get_adcp_capabilities governance.creative_features. That catalog only discovers the feature vocabulary the preset emits. An unknown id degrades to seller-default ranking (advisory errors[] note), not a failure.'
        ),
    ]

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 eval_budget : EvalBudget | None
var evaluator_id : str
var ext : ExtensionObject | None
var feature_agent : FeatureAgent | None
var feature_requirement : list[FeatureRequirement] | None
var model_config
var rank_by : list[RankByItem1] | None

Inherited members

class EvaluatorSpec3 (**data: Any)
Expand source code
class EvaluatorSpec3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    feature_requirement: Annotated[
        list[feature_requirement_1.FeatureRequirement] | None,
        Field(
            description='Optional hard GATE over creative-feature values — the predicates a leaf MUST satisfy for the producing agent to recommend/return it. Reuses the feature-requirement shape (min_value/max_value for quantitative features like creative_quality_score, allowed_values for binary/categorical) — the same predicate vocabulary that gates property/audience filters, which its own schema names as an intended creative-gate reuse. A leaf that fails any predicate is DROPPED from the agent\'s best_of_n survivors before ranking — this is internal pruning of which leaves the agent recommends, not an AdCP-layer block of an already-produced billable leaf (what is produced/billed is governed by max_variants/max_creatives/max_spend). Distinct from `rank_by`: the gate is a pass/fail predicate (drop on fail), `rank_by` is an ordering over survivors. Each predicate\'s `if_not_covered` (exclude|include, default exclude) is the fail-open knob when the source cannot measure that feature. A pass/warn/fail verdict is expressed as a categorical string feature value gated via `allowed_values` (e.g. ["pass"] or ["pass","warn"]) — the buyer\'s predicate decides whether warn passes; the verdict is derived, never stored on creative-feature-result. Omit to leave evaluation advisory (no leaf is dropped).',
            min_length=1,
        ),
    ] = None
    rank_by: Annotated[
        list[RankByItem2] | None,
        Field(
            description='Optional RANK ordering over creative-feature values — an ordered list (most significant first) the agent uses to order the gate survivors into recommended/rank. An explicit {feature_id, direction} ordering rather than the feature-requirement predicate (which has no sort direction): the gate decides pass/fail, rank_by decides better/worse. Soft preference, never a gate: leaves are not dropped by rank_by, they are only ordered. Omit to let the evaluator/seller choose the ordering.',
            min_length=1,
        ),
    ] = None
    feature_agent: Annotated[
        FeatureAgent | None,
        Field(
            description="Optional buyer-attached pointer to a get_creative_features-capable creative-feature / governance agent the producing agent calls to evaluate each leaf (the gate's SOURCE of feature values). This is the buyer-represents → seller-calls pattern #5280 established for provenance, generalized to the evaluator gate: the buyer REPRESENTS which agent it used, but the seller is the verifier-of-record and decides which agent it actually calls. `agent_url` MUST appear (canonicalized per /docs/reference/url-canonicalization) in the seller's `creative_policy.accepted_verifiers[].agent_url`; an off-list agent is rejected with `EVALUATOR_AGENT_NOT_ACCEPTED` (mirrors PROVENANCE_VERIFIER_NOT_ACCEPTED) before any outbound call. The outbound evaluator call authenticates on the transport; this pointer MUST NOT carry API keys, bearer tokens, client secrets, authorization values, JWKs, JWKS documents, or JWKS URIs. Reuses the same allowlist mechanism — no new allowlist is introduced. Distinct from the `agent_url` oneOf form, which names the evaluator's source directly; `feature_agent` attaches the gate's measurement source alongside any of the three forms."
        ),
    ] = None
    eval_budget: Annotated[
        EvalBudget | None,
        Field(
            description='Optional soft ceiling on evaluation effort. Advisory in v1 with no billing coupling. Well-known soft fields max_calls / max_seconds; open for evaluator-specific knobs.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None
    agent_url: Annotated[
        AnyUrl,
        Field(
            description="URL of an external get_creative_features-capable judge agent the seller calls to score the produced leaves. MUST match an entry in the seller's `creative_policy.accepted_verifiers[].agent_url` (off-list → `EVALUATOR_AGENT_NOT_ACCEPTED`); an on-list agent that is unreachable or rejects the producing agent's transport authentication degrades to seller-default ranking (advisory errors[] note), not a failure. Authentication and trust material for this call belongs on the transport or in account provisioning, not in the evaluator payload."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var eval_budget : EvalBudget | None
var ext : ExtensionObject | None
var feature_agent : FeatureAgent | None
var feature_requirement : list[FeatureRequirement] | None
var model_config
var rank_by : list[RankByItem2] | None

Inherited members

class Event (**data: Any)
Expand source code
class Event(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    event_id: Annotated[
        str,
        Field(
            description='Unique identifier for deduplication (scoped to event_type + event_source_id)',
            max_length=256,
            min_length=1,
        ),
    ]
    event_type: Annotated[event_type_1.EventType, Field(description='Standard event type')]
    event_time: Annotated[
        AwareDatetime, Field(description='ISO 8601 timestamp when the event occurred')
    ]
    user_match: Annotated[
        user_match_1.UserMatch | None,
        Field(description='User identifiers for attribution matching'),
    ] = None
    custom_data: Annotated[
        event_custom_data.EventCustomData | None,
        Field(description='Event-specific data (value, currency, items, etc.)'),
    ] = None
    action_source: Annotated[
        action_source_1.ActionSource | None, Field(description='Where the event originated')
    ] = None
    surface: Annotated[
        event_surface.EventSurface | None,
        Field(
            description='Optional structured surface context for the event, such as an owned channel, profile, feed, podcast, newsletter list, website, app, or store. Complements `action_source`; use it when optimization-relevant meaning would otherwise live only in platform-specific `ext` metadata.'
        ),
    ] = None
    event_source_url: Annotated[
        AnyUrl | None,
        Field(
            description="URL where the event occurred (required when action_source is 'website')"
        ),
    ] = None
    custom_event_name: Annotated[
        str | None, Field(description="Name for custom events (used when event_type is 'custom')")
    ] = None
    ext: ext_1.ExtensionObject | 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 action_source : ActionSource | None
var custom_data : EventCustomData | None
var custom_event_name : str | None
var event_id : str
var event_source_url : pydantic.networks.AnyUrl | None
var event_time : pydantic.types.AwareDatetime
var event_type : EventType
var ext : ExtensionObject | None
var model_config
var surface : EventSurface | None
var user_match : UserMatch | None

Inherited members

class EventCustomData (**data: Any)
Expand source code
class EventCustomData(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    value: Annotated[
        StrictFloat | None,
        Field(
            description='Monetary value of the event. For an event source that declares value_currencies, currency is required and MUST appear in that list. Legacy sources without the new contract remain schema-compatible but are ineligible for canonical ROAS.',
            ge=0.0,
        ),
    ] = None
    currency: Annotated[
        str | None,
        Field(
            description='ISO 4217 currency code. For a source declaring value_currencies, monetary records MUST carry a currency from that list.',
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    order_id: Annotated[str | None, Field(description='Unique order or transaction identifier')] = (
        None
    )
    content_ids: Annotated[
        list[str] | None,
        Field(
            description="Item identifiers for catalog attribution. Values are matched against catalog items using the identifier type declared by the catalog's content_id_type field (e.g., SKUs, GTINs, or vertical-specific IDs like job_id)."
        ),
    ] = None
    content_type: Annotated[
        str | None,
        Field(
            description="Category of content associated with the event (e.g., 'product', 'job', 'hotel'). Corresponds to the catalog type when used for catalog attribution."
        ),
    ] = None
    content_name: Annotated[str | None, Field(description='Name of the product or content')] = None
    content_category: Annotated[
        str | None, Field(description='Category of the product or content')
    ] = None
    num_items: Annotated[
        SchemaInt | None, Field(description='Number of items in the event', ge=0)
    ] = None
    search_string: Annotated[str | None, Field(description='Search query for search events')] = None
    progress_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Content progress percentage reached, primarily for `watch_milestone` events. Use 25, 50, 75, or 100 for quartiles, or another publisher-defined threshold. Do not use `value` for non-monetary progress.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    progress_seconds: Annotated[
        StrictFloat | None,
        Field(
            description='Content progress duration reached in seconds, primarily for `watch_milestone` events. Use when the milestone is time-based rather than percentage-based.',
            ge=0.0,
        ),
    ] = None
    contents: Annotated[
        list[Content] | None, Field(description='Per-item details for e-commerce events')
    ] = None
    ext: ext_1.ExtensionObject | 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 content_category : str | None
var content_ids : list[str] | None
var content_name : str | None
var content_type : str | None
var contents : list[Content] | None
var currency : str | None
var ext : ExtensionObject | None
var model_config
var num_items : int | None
var order_id : str | None
var progress_percent : float | None
var progress_seconds : float | None
var search_string : str | None
var value : float | None

Inherited members

class EventSourceHealth (**data: Any)
Expand source code
class EventSourceHealth(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        assessment_status.AssessmentStatus,
        Field(
            description="Overall health status. Use this for cross-seller decisions — do not rely on detail.score for comparability. 'insufficient' covers the source-offline case (zero events received over the seller's evaluation window) — disambiguate via `events_received_24h: 0` and a stale `last_event_at`. Sellers MUST surface a corresponding impairment (reason_code: source_offline) on any active media buy whose conversion goals depend on an event source that has gone offline."
        ),
    ]
    detail: Annotated[
        Detail | None,
        Field(
            description='Seller-specific scoring detail. Only present when the seller has a native quality score to relay. Buyer agents should use status (not detail) for cross-seller decisions. Detail is supplementary context for human review or advanced diagnostics.'
        ),
    ] = None
    match_rate: Annotated[
        StrictFloat | None,
        Field(
            description='Fraction of events from this source that the seller successfully matched to ad interactions (0.0-1.0). Low match rates indicate weak user_match identifiers. Absent when the seller does not compute match rates.',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    last_event_at: Annotated[
        AwareDatetime | None,
        Field(
            description='ISO 8601 timestamp of the most recent event received from this source. Absent when no events have been received.'
        ),
    ] = None
    evaluated_at: Annotated[
        AwareDatetime | None,
        Field(
            description='ISO 8601 timestamp of when this health assessment was computed. When health is derived from reporting data, this may lag real-time. Buyer agents can use this to decide whether to trust stale assessments or re-request.'
        ),
    ] = None
    events_received_24h: Annotated[
        SchemaInt | None,
        Field(
            description='Number of events received from this source in the last 24 hours. Zero indicates the source is configured but not firing.',
            ge=0,
        ),
    ] = None
    issues: Annotated[
        list[diagnostic_issue.DiagnosticIssue] | None,
        Field(
            description='Actionable issues detected with this event source. Sellers should limit to the top 3-5 most actionable items. Buyer agents should sort by severity rather than relying on array position.'
        ),
    ] = 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 detail : Detail | None
var evaluated_at : pydantic.types.AwareDatetime | None
var events_received_24h : int | None
var issues : list[DiagnosticIssue] | None
var last_event_at : pydantic.types.AwareDatetime | None
var match_rate : float | None
var model_config
var status : AssessmentStatus

Inherited members

class EventSurface (**data: Any)
Expand source code
class EventSurface(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    category: Annotated[
        Category,
        Field(
            description='Generic surface category. `owned_property` covers durable creator or brand-controlled properties hosted by a platform, such as channels, profiles, feeds, lists, podcasts, or playlists.'
        ),
    ]
    property_type: Annotated[
        str | None,
        Field(
            description='Open vocabulary describing the kind of property, for example `channel`, `profile`, `feed`, `list`, `podcast`, `playlist`, or `newsletter`. Required by convention when `category` is `owned_property`; optional for other categories.',
            max_length=128,
            min_length=1,
        ),
    ] = None
    namespace: Annotated[
        str | None,
        Field(
            description='Platform, publisher, or system namespace for the property, such as `video_platform`, `short_video_app`, `audio_service`, or a seller-defined namespace. This is intentionally not an enum.',
            max_length=128,
            min_length=1,
        ),
    ] = None
    property_id: Annotated[
        str | None,
        Field(
            description='Optional identifier for the property within `namespace`.',
            max_length=256,
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 category : Category
var ext : ExtensionObject | None
var model_config
var namespace : str | None
var property_id : str | None
var property_type : str | None

Inherited members

class ExcludedCountry (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ExcludedCountry(Country):
    pass

A str generated from a JSON Schema string root.

Ancestors

  • Country
  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class Exclusion (**data: Any)
Expand source code
class Exclusion(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    axis: Axis
    value: Annotated[str, Field(max_length=128, min_length=1)]
    reason: Annotated[
        str,
        Field(
            description='Why this declared value is absent from the accepted intersection, such as unsupported by this seller or retired. Untrusted display data; never executed as instructions.',
            max_length=512,
            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 axis : Axis
var model_config
var reason : str
var value : str

Inherited members

class Execution (**data: Any)
Expand source code
class Execution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Literal['continuous_bounds'] = 'continuous_bounds'
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var model_config
var type : Literal['continuous_bounds']

Inherited members

class Execution1 (**data: Any)
Expand source code
class Execution1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Literal['enumerated_intervals'] = 'enumerated_intervals'
    interval_ids: Annotated[
        list[IntervalId],
        Field(
            description='Seller-scoped interval identifiers whose union produced applied.',
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var interval_ids : list[IntervalId]
var model_config
var type : Literal['enumerated_intervals']

Inherited members

class Execution2 (**data: Any)
Expand source code
class Execution2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Literal['signals'] = 'signals'
    signal_refs: Annotated[
        list[signal_ref.SignalRef],
        Field(
            description='Authoritative signal references whose demographic predicates were unioned to produce applied. Signal names alone never establish equivalence.',
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var model_config
var signal_refs : list[SignalRef1 | SignalRef2 | SignalRef3]
var type : Literal['signals']

Inherited members

class ExecutionMode (*args, **kwds)
Expand source code
class ExecutionMode(StrEnum):
    continuous_bounds = 'continuous_bounds'
    enumerated_intervals = 'enumerated_intervals'
    signals = 'signals'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var continuous_bounds
var enumerated_intervals
var signals
class Exemplars (**data: Any)
Expand source code
class Exemplars(AdCPBaseModel):
    pass_: Annotated[
        list[artifact.Artifact] | None,
        Field(
            alias='pass',
            description='Artifacts exemplifying variants the buyer considers good — the high end (≈1) of the calibrated prediction feature.',
        ),
    ] = None
    fail: Annotated[
        list[artifact.Artifact] | None,
        Field(
            description='Artifacts exemplifying variants the buyer considers bad — the low end (≈0) of the calibrated prediction feature.'
        ),
    ] = 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 fail : list[Artifact] | None
var model_config
var pass_ : list[Artifact] | None

Inherited members

class ExperienceLevel (*args, **kwds)
Expand source code
class ExperienceLevel(StrEnum):
    entry_level = 'entry_level'
    mid_level = 'mid_level'
    senior = 'senior'
    director = 'director'
    executive = 'executive'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var director
var entry_level
var executive
var mid_level
var senior
class ExperimentalFeatureId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ExperimentalFeatureId(ScalarStr):
    __slots__ = ()
    _constraints = {
        'max_length': 128,
        'min_length': 1,
        'pattern': '^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$',
    }
    _json_schema_extra = {
        'description': 'Dot-separated lowercase identifier for an experimental AdCP surface, such as protocol.principal or media_buy.reporting_delivery.',
        'title': 'Experimental Feature ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class Ext (**data: Any)
Expand source code
class Ext(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class ExtensionObject (**data: Any)
Expand source code
class ExtensionObject(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class FailureCode (*args, **kwds)
Expand source code
class FailureCode(StrEnum):
    access_denied = 'access_denied'
    resource_not_found = 'resource_not_found'
    integrity_mismatch = 'integrity_mismatch'
    reader_incompatible = 'reader_incompatible'
    transport_failed = 'transport_failed'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var access_denied
var integrity_mismatch
var reader_incompatible
var resource_not_found
var transport_failed
class FeatureAgent (**data: Any)
Expand source code
class FeatureAgent(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[
        AnyUrl,
        Field(
            description="URL of the get_creative_features-capable agent the producing agent calls to obtain creative-feature values for the gate. MUST use https:// and MUST match an entry in the seller's `creative_policy.accepted_verifiers[].agent_url`; off-list → `EVALUATOR_AGENT_NOT_ACCEPTED`."
        ),
    ]
    feature_id: Annotated[
        str | None,
        Field(
            description="Optional canonical feature_id the producing agent SHOULD request against this agent. When present it SHOULD match the agent's `accepted_verifiers[].feature_id` or be omitted; when absent the seller selects a feature at evaluation time. Resolves selector ambiguity exactly as the provenance verify_agent.feature_id does."
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var feature_id : str | None
var model_config

Inherited members

class FeatureRequirement (**data: Any)
Expand source code
class FeatureRequirement(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    feature_id: Annotated[
        str, Field(description='Feature to evaluate (discovered via get_adcp_capabilities)')
    ]
    min_value: Annotated[
        StrictFloat | None,
        Field(description='Minimum numeric value required (for quantitative features)'),
    ] = None
    max_value: Annotated[
        StrictFloat | None,
        Field(description='Maximum numeric value allowed (for quantitative features)'),
    ] = None
    allowed_values: Annotated[
        list[Any] | None,
        Field(
            description='Values that pass the requirement (for binary/categorical features)',
            min_length=1,
        ),
    ] = None
    if_not_covered: Annotated[
        IfNotCovered | None,
        Field(
            description="How to handle properties where this feature is not covered. 'exclude' (default): property is removed from the list. 'include': property passes this requirement (fail-open)."
        ),
    ] = IfNotCovered.exclude
    policy_id: Annotated[
        str | None,
        Field(
            description='Optional attribution — when this requirement encodes a specific buyer-chosen threshold authorized by a policy, policy_id references the authorizing PolicyEntry. Producers populate when the mechanism exists because of a specific policy (e.g., max_value: 15 on audience_children_composition because of uk_hfss); do NOT populate when the requirement is a general filter unrelated to any policy. Governance findings echo this policy_id when emitting denials traced to the requirement. See /docs/governance/policy-attribution.'
        ),
    ] = 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 allowed_values : list[typing.Any] | None
var feature_id : str
var if_not_covered : IfNotCovered | None
var max_value : float | None
var min_value : float | None
var model_config
var policy_id : str | None

Inherited members

class FeedFormat (*args, **kwds)
Expand source code
class FeedFormat(StrEnum):
    google_merchant_center = 'google_merchant_center'
    facebook_catalog = 'facebook_catalog'
    shopify = 'shopify'
    linkedin_jobs = 'linkedin_jobs'
    tiktok_shop = 'tiktok_shop'
    pinterest_catalog = 'pinterest_catalog'
    openai_product_feed = 'openai_product_feed'
    custom = 'custom'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var custom
var facebook_catalog
var google_merchant_center
var linkedin_jobs
var openai_product_feed
var pinterest_catalog
var shopify
var tiktok_shop
class Field0 (**data: Any)
Expand source code
class Field0(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Annotated[
        Literal['standard'],
        Field(description='Standard metric from the closed `available-metric.json` enum.'),
    ] = 'standard'
    metric_id: Annotated[
        available_metric.AvailableMetric,
        Field(
            description='Identifier for a scalar standard metric. Container tokens and structured distribution identities are committed and selected through their canonical carriers, not represented as numeric aggregate rows.'
        ),
    ]
    qualifier: Annotated[
        Qualifier | None,
        Field(
            description="Qualifier keys disambiguating this row from sibling rows under the same `metric_id`. Symmetric with `committed_metrics.qualifier` today; expected to diverge in future minors as transparency disclosures buyers don't commit to ship delivery-only. Closed (`additionalProperties: false`) — new qualifier keys ship explicitly."
        ),
    ] = None
    value: Annotated[
        StrictFloat,
        Field(
            description='Aggregated metric value for this `(metric_id, qualifier)` partition. Heterogeneous by `metric_id` — rate metrics (`viewable_rate`, `completion_rate`) are 0.0–1.0; cost-per metrics (`cost_per_acquisition`, `cost_per_completed_view`) are currency amounts; count metrics (`impressions`, `clicks`) are non-negative integers as numbers; ratio metrics (`roas`) are non-negative numbers. Buyer agents MUST inspect `metric_id` before doing arithmetic — same dispatch convention as `committed_metrics`.'
        ),
    ]
    measurable_impressions: Annotated[
        StrictFloat | None,
        Field(
            description='Coverage denominator for verification metrics (e.g., `viewable_rate`). Buyers compute coverage as `measurable_impressions / impressions` from the partition.',
            ge=0.0,
        ),
    ] = None
    viewable_impressions: Annotated[
        StrictFloat | None, Field(description='Component for `viewable_rate` (numerator).', ge=0.0)
    ] = None
    impressions: Annotated[
        StrictFloat | None,
        Field(
            description='Component for rate metrics whose denominator is total impressions (e.g., `completion_rate`, `engagement_rate`).',
            ge=0.0,
        ),
    ] = None
    completed_views: Annotated[
        StrictFloat | None,
        Field(description='Component for `completion_rate` (numerator).', ge=0.0),
    ] = None
    spend: Annotated[
        StrictFloat | None,
        Field(
            description='Component for cost-per metrics (denominator-ish; the cost half of the ratio).',
            ge=0.0,
        ),
    ] = None
    conversions: Annotated[
        StrictFloat | None,
        Field(description='Component for `cost_per_acquisition` and ROAS-family metrics.', ge=0.0),
    ] = None
    conversion_value: Annotated[
        StrictFloat | None, Field(description='Component for `roas` (numerator).', ge=0.0)
    ] = None
    clicks: Annotated[
        StrictFloat | None,
        Field(description='Component for `cost_per_click` and click-rate metrics.', ge=0.0),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var clicks : float | None
var completed_views : float | None
var conversion_value : float | None
var conversions : float | None
var impressions : float | None
var measurable_impressions : float | None
var metric_id : AvailableMetric
var model_config
var qualifier : Qualifier | None
var scope : Literal['standard']
var spend : float | None
var value : float
var viewable_impressions : float | None

Inherited members

class FieldModel (*args, **kwds)
Expand source code
class FieldModel(StrEnum):
    url = 'url'
    markup = 'markup'
    content = 'content'
    ad_request_url = 'ad_request_url'
    clickthrough_url = 'clickthrough_url'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var ad_request_url
var clickthrough_url
var content
var markup
var url
class FieldTruncation (**data: Any)
Expand source code
class FieldTruncation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    original_size_bytes: Annotated[
        SchemaInt,
        Field(
            description='Size of the untruncated original content in bytes, measured before any encoding overhead. Lets the receiver decide whether to fetch the full value via a payload-bearing surface (when one exists) or proceed with the preview.',
            ge=0,
        ),
    ]
    preview: Annotated[
        str | None,
        Field(
            description='Optional bounded human-readable excerpt of the original content. Sellers SHOULD keep previews under 8 KiB and SHOULD truncate on a UTF-8 codepoint boundary. Absent when the seller cannot safely surface even a preview (e.g., the original content is binary and not text-decodable, or seller policy forbids any payload surfacing). Receivers MUST NOT parse `preview` as a complete representation of the original value.'
        ),
    ] = None
    preview_format: Annotated[
        str | None,
        Field(
            description='Hint for how to render `preview`. Common values: `text` (plain UTF-8), `json` (JSON fragment), `base64` (base64-encoded binary), `xml`, `html`. The list is open — adopters MAY use other MIME-derived shorthands. Receivers SHOULD treat unknown values as `text` and SHOULD NOT reject the sentinel when the value is unfamiliar.'
        ),
    ] = 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 model_config
var original_size_bytes : int
var preview : str | None
var preview_format : str | None

Inherited members

class Filters (**data: Any)
Expand source code
class Filters(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    protocol: Annotated[
        adcp_protocol.AdcpProtocol | None, Field(description='Filter by single AdCP protocol')
    ] = None
    protocols: Annotated[
        list[adcp_protocol.AdcpProtocol] | None,
        Field(description='Filter by multiple AdCP protocols', min_length=1),
    ] = None
    status: Annotated[
        task_status.TaskStatus | None, Field(description='Filter by single task status')
    ] = None
    statuses: Annotated[
        list[task_status.TaskStatus] | None,
        Field(description='Filter by multiple task statuses', min_length=1),
    ] = None
    task_type: Annotated[
        task_type_1.TaskType | None, Field(description='Filter by single task type')
    ] = None
    task_types: Annotated[
        list[task_type_1.TaskType] | None,
        Field(description='Filter by multiple task types', min_length=1),
    ] = None
    created_after: Annotated[
        AwareDatetime | None, Field(description='Filter tasks created after this date (ISO 8601)')
    ] = None
    created_before: Annotated[
        AwareDatetime | None, Field(description='Filter tasks created before this date (ISO 8601)')
    ] = None
    updated_after: Annotated[
        AwareDatetime | None,
        Field(description='Filter tasks last updated after this date (ISO 8601)'),
    ] = None
    updated_before: Annotated[
        AwareDatetime | None,
        Field(description='Filter tasks last updated before this date (ISO 8601)'),
    ] = None
    task_ids: Annotated[
        list[str] | None,
        Field(description='Filter by specific task IDs', max_length=100, min_length=1),
    ] = None
    context_contains: Annotated[
        str | None,
        Field(
            description='Filter tasks where context contains this text (searches media_buy_id, signal_id, etc.)'
        ),
    ] = None
    has_webhook: Annotated[
        StrictBool | None,
        Field(description='Filter tasks that have webhook configuration when true'),
    ] = 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 context_contains : str | None
var created_after : pydantic.types.AwareDatetime | None
var created_before : pydantic.types.AwareDatetime | None
var has_webhook : bool | None
var model_config
var protocol : AdcpProtocol | None
var protocols : list[AdcpProtocol] | None
var status : TaskStatus | None
var statuses : list[TaskStatus] | None
var task_ids : list[str] | None
var task_type : TaskType | None
var task_types : list[TaskType] | None
var updated_after : pydantic.types.AwareDatetime | None
var updated_before : pydantic.types.AwareDatetime | None

Inherited members

class FinalityBasis (*args, **kwds)
Expand source code
class FinalityBasis(StrEnum):
    source_final = 'source_final'
    contractual_cutoff = 'contractual_cutoff'
    stabilized = 'stabilized'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var contractual_cutoff
var source_final
var stabilized
class FinalityPolicies (**data: Any)
Expand source code
class FinalityPolicies(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    finality_policy_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    basis: Literal['source_final'] = 'source_final'
    source_signal: Annotated[str, Field(max_length=512, 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 basis : Literal['source_final']
var finality_policy_id : str
var model_config
var source_signal : str

Inherited members

class FinalityPolicies1 (**data: Any)
Expand source code
class FinalityPolicies1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    finality_policy_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    basis: Literal['contractual_cutoff'] = 'contractual_cutoff'
    duration_after_period_end: Annotated[
        str,
        Field(
            pattern='^P(?=\\d|T)(?=.*\\d)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$'
        ),
    ]

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 basis : Literal['contractual_cutoff']
var duration_after_period_end : str
var finality_policy_id : str
var model_config

Inherited members

class FinalityPolicies2 (**data: Any)
Expand source code
class FinalityPolicies2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    finality_policy_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    basis: Literal['stabilized'] = 'stabilized'
    minimum_age: Annotated[
        str,
        Field(
            pattern='^P(?=\\d|T)(?=.*\\d)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$'
        ),
    ]
    unchanged_for: Annotated[
        str,
        Field(
            pattern='^P(?=\\d|T)(?=.*\\d)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$'
        ),
    ]

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 basis : Literal['stabilized']
var finality_policy_id : str
var minimum_age : str
var model_config
var unchanged_for : str

Inherited members

class Fit (*args, **kwds)
Expand source code
class Fit(StrEnum):
    contain = 'contain'
    cover = 'cover'
    stretch = 'stretch'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var contain
var cover
var stretch
class FlightItem (**data: Any)
Expand source code
class FlightItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    flight_id: Annotated[
        str, Field(description='Unique identifier for this flight route or offer.')
    ]
    origin: Annotated[Origin, Field(description='Departure airport or city.')]
    destination: Annotated[Destination, Field(description='Arrival airport or city.')]
    airline: Annotated[str | None, Field(description='Airline name or IATA airline code.')] = None
    price: Annotated[price_1.Price | None, Field(description='Ticket price or starting fare.')] = (
        None
    )
    description: Annotated[
        str | None, Field(description='Route description or promotional text.')
    ] = None
    departure_time: Annotated[
        AwareDatetime | None, Field(description='Departure date and time (ISO 8601).')
    ] = None
    arrival_time: Annotated[
        AwareDatetime | None, Field(description='Arrival date and time (ISO 8601).')
    ] = None
    image_url: Annotated[
        AnyUrl | None, Field(description='Promotional image URL (typically a destination photo).')
    ] = None
    url: Annotated[AnyUrl | None, Field(description='Booking page URL for this route.')] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering (e.g., 'direct', 'red-eye', 'business-class').",
            min_length=1,
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this flight. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (destination hero), 'images_vertical' (9:16 for Stories), 'images_square' (1:1). Enables formats to declare typed image requirements that map unambiguously to the right asset regardless of platform.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 airline : str | None
var arrival_time : pydantic.types.AwareDatetime | None
var assets : list[OfferingAssetGroup] | None
var departure_time : pydantic.types.AwareDatetime | None
var description : str | None
var destination : Destination
var ext : ExtensionObject | None
var flight_id : str
var image_url : pydantic.networks.AnyUrl | None
var model_config
var origin : Origin
var price : Price | None
var tags : list[str] | None
var url : pydantic.networks.AnyUrl | None

Inherited members

class ForecastPoint (**data: Any)
Expand source code
class ForecastPoint(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    label: Annotated[
        str | None,
        Field(
            description="Human-readable name for this forecast point. Required when forecast_range_unit is 'package' so buyer agents can identify and reference individual packages. Optional for other forecast types.",
            examples=['Primetime', 'Morning Drive', 'Large Format Transit'],
            max_length=128,
        ),
    ] = None
    budget: Annotated[
        StrictFloat | None,
        Field(
            description='Budget amount for this forecast point. Required for spend curves; omit for availability forecasts where the metrics represent total available inventory. For allocation-level forecasts, this is the absolute budget for that allocation (not the percentage). For proposal-level forecasts, this is the total proposal budget. When omitted, use metrics.spend to express the estimated cost of the available inventory.',
            ge=0.0,
        ),
    ] = None
    product_id: Annotated[
        str | None,
        Field(
            description='Optional product context for this forecast row. Usually omitted on product-level and allocation-level forecasts where the product is already implied. On proposal-level forecasts, populate when a dimensional row, especially a placement row, maps to a specific product allocation so buyers can turn the row into an executable package choice. Omit for true aggregate proposal rows spanning multiple products.'
        ),
    ] = None
    dimensions: Annotated[
        forecast_point_dimensions.ForecastPointDimensions | None,
        Field(
            description='Dimension constraints represented by this forecast point, such as country, region, placement, device type, platform, audience, signal value, time window, or intersections such as placement x country or product x signal. Each item declares one dimension family; when multiple items are present, the point represents their intersection. Sellers MUST NOT emit more than one item for each `kind` on a point; consumers MUST NOT treat repeated kinds as OR semantics. Use multiple points with dimensions to expose country/placement/signal availability within one product, proposal, or signal coverage forecast without creating separate products solely for each dimension. Dimensions describe the forecast row and are independent of pricing_options.'
        ),
    ] = None
    availability_status: Annotated[
        availability_status_1.AvailabilityStatus | None,
        Field(
            description="Bookability of the inventory this row describes, as of the forecast's generated_at. Most meaningful on rows with a time dimension in an availability forecast (forecast_range_unit 'availability'). This is a snapshot, not a hold: valid_until bounds freshness, and proposal finalization or purchase remains the commitment boundary. When omitted, the row makes no bookability claim. 'unavailable' rows may carry empty metrics."
        ),
    ] = None
    metrics: Annotated[
        Metrics,
        Field(
            description='Forecasted metric values. Keys are forecastable-metric enum values for delivery/engagement or event-type enum values for outcomes. Values are ForecastRange objects (low/mid/high). Use { "mid": value } for point estimates. When budget is present, these are the expected metrics at that spend level. When budget is omitted, these represent total available inventory — use spend to express the estimated cost. Additional keys beyond the documented properties are allowed for event-type values (purchase, lead, app_install, etc.).'
        ),
    ]
    viewability: Annotated[
        Viewability | None,
        Field(
            description='Forecasted viewability metrics. Mirrors delivery-metrics.viewability, but numeric values are ForecastRange objects because forecast rows may provide low/mid/high bounds. Use this for pre-buy viewability expectations by forecast point without folding measurement metrics into pricing_options.'
        ),
    ] = None
    vendor_metric_values: Annotated[
        list[forecast_vendor_metric_value.ForecastVendorMetricValue] | None,
        Field(
            description="Forecasted values for vendor-defined metrics that the product's reporting_capabilities.vendor_metrics declared. Mirrors delivery-metrics.vendor_metric_values, but value and measurable_impressions use ForecastRange. These forecasted measurement values are independent of pricing_options."
        ),
    ] = 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 availability_status : AvailabilityStatus | None
var budget : float | None
var dimensions : ForecastPointDimensions | None
var label : str | None
var metrics : Metrics
var model_config
var product_id : str | None
var vendor_metric_values : list[ForecastVendorMetricValue] | None
var viewability : Viewability | None

Inherited members

class ForecastPointDimensions (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class ForecastPointDimensions(
    RootModel[
        list[
            forecast_dimension_geo.GeoForecastDimension
            | forecast_dimension_placement.PlacementForecastDimension
            | forecast_dimension_device_type.DeviceTypeForecastDimension
            | forecast_dimension_device_platform.DevicePlatformForecastDimension
            | forecast_dimension_audience.AudienceForecastDimension
            | forecast_dimension_signal.SignalForecastDimension
            | forecast_dimension_time.TimeForecastDimension
        ]
    ]
):
    root: Annotated[
        list[
            forecast_dimension_geo.GeoForecastDimension
            | forecast_dimension_placement.PlacementForecastDimension
            | forecast_dimension_device_type.DeviceTypeForecastDimension
            | forecast_dimension_device_platform.DevicePlatformForecastDimension
            | forecast_dimension_audience.AudienceForecastDimension
            | forecast_dimension_signal.SignalForecastDimension
            | forecast_dimension_time.TimeForecastDimension
        ],
        Field(
            description='Dimension constraints represented by a ForecastPoint. Use this when one product, proposal, or signal coverage forecast needs to expose availability or forecasted delivery by country, region, placement, device, audience, signal value, time window, or intersections such as placement x country without creating separate products solely for each slice. Each item declares one dimension family via `kind`; when multiple items are present, the point represents their intersection. Sellers MUST NOT emit more than one item for each `kind` in a point. Consumers MUST NOT treat repeated kinds as OR semantics; repeated peer values such as two countries are a seller conformance issue. Dimension values are descriptors of the forecast row and are independent of pricing_options.',
            min_length=1,
            title='Forecast Point Dimensions',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[list[Union[GeoForecastDimension, PlacementForecastDimension, DeviceTypeForecastDimension, DevicePlatformForecastDimension, AudienceForecastDimension, SignalForecastDimension, TimeForecastDimension]]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[GeoForecastDimension | PlacementForecastDimension | DeviceTypeForecastDimension | DevicePlatformForecastDimension | AudienceForecastDimension | SignalForecastDimension | TimeForecastDimension]
class ForecastRange (**data: Any)
Expand source code
class ForecastRange(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    low: Annotated[
        StrictFloat | None, Field(description='Conservative (low-end) forecast value', ge=0.0)
    ] = None
    mid: Annotated[
        StrictFloat | None, Field(description='Expected (most likely) forecast value', ge=0.0)
    ] = None
    high: Annotated[
        StrictFloat | None, Field(description='Optimistic (high-end) forecast value', ge=0.0)
    ] = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> ForecastRange:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('mid',), ('low', 'high'),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'ForecastRange requires at least one of these field groups: mid | low+high'
        )

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 high : float | None
var low : float | None
var mid : float | None
var model_config

Inherited members

class ForecastRateRange (**data: Any)
Expand source code
class ForecastRateRange(ForecastRange):
    low: Annotated[
        StrictFloat | None,
        Field(description='Conservative (low-end) forecast value', ge=0.0, le=1.0),
    ] = None
    mid: Annotated[
        StrictFloat | None,
        Field(description='Expected (most likely) forecast value', ge=0.0, le=1.0),
    ] = None
    high: Annotated[
        StrictFloat | None,
        Field(description='Optimistic (high-end) forecast value', ge=0.0, le=1.0),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var high : float | None
var low : float | None
var mid : float | None
var model_config

Inherited members

class ForecastVendorMetricValue (**data: Any)
Expand source code
class ForecastVendorMetricValue(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description='Vendor that defines and forecasts this metric. Matches a reporting_capabilities.vendor_metrics declaration on the product.'
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(
            description="Identifier for the metric within the vendor's vocabulary. Matches a vendor_metrics[].metric_id declaration on the product."
        ),
    ]
    value: Annotated[
        forecast_range.ForecastRange,
        Field(
            description="Forecasted vendor metric value. Unit semantics are vendor-defined; see unit and the vendor's measurement-agent metric definition."
        ),
    ]
    unit: Annotated[
        str | None,
        Field(
            description="Unit of the value. Free-form to accommodate heterogeneous vendor metrics (e.g., 'score', 'seconds', 'persons', 'gCO2e', 'USD', 'lift_percent', 'index'). When populated inline, SHOULD match the vendor's published unit.",
            examples=['score', 'seconds', 'persons', 'gCO2e', 'USD', 'lift_percent', 'index'],
        ),
    ] = None
    measurable_impressions: Annotated[
        forecast_range.ForecastRange | None,
        Field(
            description='Forecasted number of impressions the vendor expects to be able to measure. Coverage denominator for the vendor metric; buyers compute estimated coverage as measurable_impressions / impressions when both are present. For play-based channels (DOOH, cinema, place-based) forecast measurable_plays or measurable_play_seconds instead.'
        ),
    ] = None
    measurable_plays: Annotated[
        forecast_range.ForecastRange | None,
        Field(
            description='Forecasted number of plays the vendor expects to be able to measure. Coverage denominator for channels where a play, not an impression, is the atomic observation unit; buyers compute estimated coverage as measurable_plays / plays when both are present.'
        ),
    ] = None
    measurable_play_seconds: Annotated[
        forecast_range.ForecastRange | None,
        Field(
            description='Forecasted play-seconds (creative playout seconds summed across endpoints — screens, speakers, players) the vendor expects to be able to measure. Coverage denominator when the vendor meters exposure duration rather than discrete plays.'
        ),
    ] = None
    breakdown: Annotated[
        dict[str, Any] | None,
        Field(
            description="Optional structured payload for vendor metrics that do not fit a single scalar. Forecast rows SHOULD use ForecastRange values inside breakdown when sub-values are numeric forecasts. Buyers MUST treat this object as opaque without consulting the vendor's documentation."
        ),
    ] = 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 breakdown : dict[str, typing.Any] | None
var measurable_impressions : ForecastRange | None
var measurable_play_seconds : ForecastRange | None
var measurable_plays : ForecastRange | None
var metric_id : VendorMetricId
var model_config
var unit : str | None
var value : ForecastRange
var vendor : BrandReference

Inherited members

class FormatCard (**data: Any)
Expand source code
class FormatCard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    format_id: Annotated[
        format_id_1.FormatReferenceStructuredObject,
        Field(
            description='Creative format defining the card layout (typically format_card_standard)'
        ),
    ]
    manifest: Annotated[
        dict[str, Any],
        Field(description='Asset manifest for rendering the card, structure defined by the format'),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_id : FormatReferenceStructuredObject
var manifest : dict[str, typing.Any]
var model_config

Inherited members

class FormatCardDetailed (**data: Any)
Expand source code
class FormatCardDetailed(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    format_id: Annotated[
        format_id_1.FormatReferenceStructuredObject,
        Field(
            description='Creative format defining the detailed card layout (typically format_card_detailed)'
        ),
    ]
    manifest: Annotated[
        dict[str, Any],
        Field(
            description='Asset manifest for rendering the detailed card, structure defined by the format'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_id : FormatReferenceStructuredObject
var manifest : dict[str, typing.Any]
var model_config

Inherited members

class FormatKind (*args, **kwds)
Expand source code
class FormatKind(StrEnum):
    image = 'image'
    html5 = 'html5'
    display_tag = 'display_tag'
    image_carousel = 'image_carousel'
    video_hosted = 'video_hosted'
    video_vast = 'video_vast'
    audio_hosted = 'audio_hosted'
    audio_vast = 'audio_vast'
    audio_daast = 'audio_daast'
    sponsored_placement = 'sponsored_placement'
    native_in_feed = 'native_in_feed'
    responsive_creative = 'responsive_creative'
    agent_placement = 'agent_placement'
    custom = 'custom'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var agent_placement
var audio_daast
var audio_hosted
var audio_vast
var custom
var display_tag
var html5
var image
var native_in_feed
var responsive_creative
var sponsored_placement
var video_hosted
var video_vast
class FormatOptionReference1 (**data: Any)
Expand source code
class FormatOptionReference1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    scope: Annotated[
        Literal['publisher'],
        Field(
            description="Reference resolves against the named publisher's adagents.json top-level `formats[]` catalog."
        ),
    ] = 'publisher'
    publisher_domain: Annotated[
        str,
        Field(
            description='Publisher domain where the adagents.json declaring this format option is hosted.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    format_option_id: Annotated[
        str,
        Field(
            description="Stable format option ID from the publisher's adagents.json top-level `formats[]`, matching a publisher-catalog-backed entry in the target product's `format_options[]`."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_option_id : str
var model_config
var publisher_domain : str
var scope : Literal['publisher']

Inherited members

class FormatOptionReference2 (**data: Any)
Expand source code
class FormatOptionReference2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    scope: Annotated[
        Literal['product'],
        Field(
            description="Reference resolves only against the target product's inline `format_options[]`."
        ),
    ] = 'product'
    format_option_id: Annotated[
        str,
        Field(
            description="Stable format option ID from the target product's inline `format_options[]`."
        ),
    ]
    publisher_domain: 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 format_option_id : str
var model_config
var publisher_domain : typing.Any | None
var scope : Literal['adcp.types.domains.core.product']

Inherited members

class FormatOptions (**data: Any)
Expand source code
class FormatOptions(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    format_option_id: Annotated[
        str, Field(description="Matches a `format_option_id` in the file's top-level `formats[]`.")
    ]
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional placement-local locale policy. When the resolved top-level format declares a policy, every placement range must be contained by one of its ranges; otherwise this introduces a narrowing of the unconstrained format. The resolved effective route remains canonical-only.'
        ),
    ] = 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 format_option_id : str
var locale_policy : CreativeLocalePolicy | None
var model_config

Inherited members

class FormatReferenceStructuredObject (**data: Any)
Expand source code
class FormatReferenceStructuredObject(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    agent_url: Annotated[
        WireUrl,
        Field(
            description="URL of the agent that defines this format (e.g., 'https://creative.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats). Callers comparing two `format-id` values MUST canonicalize `agent_url` per the AdCP URL canonicalization rules before treating two formats as the same. See docs/reference/url-canonicalization."
        ),
    ]
    id: Annotated[
        str,
        Field(
            description="Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant.",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description='Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.',
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.',
            ge=1,
        ),
    ] = None
    duration_ms: Annotated[
        StrictFloat | None,
        Field(
            description='Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters.',
            ge=1.0,
        ),
    ] = None
    pixel_ratio: Annotated[
        StrictFloat | None,
        Field(
            description='Required intrinsic-pixel density for a parameterized visual format, expressed as intrinsic pixels per logical pixel. Requires `width` and `height`. Example: `{id: "display_image", width: 300, height: 250, pixel_ratio: 2}` identifies a 300×250 logical render supplied by a 600×500 image. Omit for the backward-compatible 1x variant.',
            gt=0.0,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : str
var duration_ms : float | None
var height : int | None
var id : str
var model_config
var pixel_ratio : float | None
var width : int | None

Inherited members

class FrameRate (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class FrameRate(ScalarFloat):
    __slots__ = ()
    _constraints = {'ge': 1.0}

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._scalar.ScalarFloat
  • adcp.types._scalar._ScalarRoot
  • builtins.float
class FrameRateType (*args, **kwds)
Expand source code
class FrameRateType(StrEnum):
    constant = 'constant'
    variable = 'variable'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var constant
var variable
class FrequencyCap (**data: Any)
Expand source code
class FrequencyCap(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    suppress: Annotated[
        duration.Duration | None,
        Field(
            description='Cooldown period between consecutive exposures to the same entity. Prevents back-to-back ad delivery (e.g. {"interval": 60, "unit": "minutes"} for a 1-hour cooldown). Preferred over suppress_minutes.'
        ),
    ] = None
    suppress_minutes: Annotated[
        StrictFloat | None,
        Field(
            deprecated=True,
            description='Deprecated — use suppress instead. Cooldown period in minutes between consecutive exposures to the same entity (e.g. 60 for a 1-hour cooldown).',
            ge=0.0,
        ),
    ] = None
    max_impressions: Annotated[
        SchemaInt | None,
        Field(
            description="Maximum number of impressions per entity per window. For duration windows, implementations typically use a rolling window. campaign applies across the owning field's full flight: the package flight for a targeting overlay, or the MediaBuy flight for a root cap.",
            ge=1,
        ),
    ] = None
    per: Annotated[
        reach_unit.ReachUnit | None,
        Field(
            description='Entity granularity for impression counting. Required when max_impressions is set.'
        ),
    ] = None
    window: Annotated[
        duration.Duration | None,
        Field(
            description='Time window for the max_impressions cap (e.g. {"interval": 7, "unit": "days"} or {"interval": 1, "unit": "campaign"} for the full flight). Required when max_impressions is set.'
        ),
    ] = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> FrequencyCap:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('suppress',), ('suppress_minutes',), ('max_impressions',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'FrequencyCap requires at least one of these field groups: suppress | suppress_minutes | max_impressions'
        )

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 max_impressions : int | None
var model_config
var per : ReachUnit | None
var suppress : Duration | None
var suppress_minutes : float | None
var window : Duration | None

Inherited members

class FrequencyCapConstraints (**data: Any)
Expand source code
class FrequencyCapConstraints(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mutable_fields: Annotated[
        list[frequency_cap_mutable_field.FrequencyCapMutableField] | None,
        Field(
            description='Logical cap fields that can change after creation. An empty array means create-only. For example, [max_impressions] permits changing the count while keeping per and window fixed. Omission means update support is undeclared and the legacy broad meaning applies.'
        ),
    ] = None
    supported_control_modes: Annotated[
        list[frequency_cap_control_mode.FrequencyCapControlMode] | None,
        Field(
            description='FrequencyCap shapes accepted by the product. max_impressions_and_suppress means both controls may appear together and are enforced with AND semantics.',
            min_length=1,
        ),
    ] = None
    supported_per_units: Annotated[
        list[reach_unit.ReachUnit] | None,
        Field(description='Entity granularities accepted by max_impressions caps.', min_length=1),
    ] = None
    max_impressions_constraints: Annotated[
        frequency_cap_impression_constraints.FrequencyCapImpressionConstraints | None,
        Field(description='Exact supported max_impressions presets or range.'),
    ] = None
    window_constraints: Annotated[
        list[frequency_cap_interval_constraints.FrequencyCapIntervalConstraints] | None,
        Field(
            description='Exact supported max_impressions.window intervals, one entry per duration unit.',
            min_length=1,
        ),
    ] = None
    suppression_constraints: Annotated[
        list[frequency_cap_interval_constraints.FrequencyCapIntervalConstraints] | None,
        Field(
            description='Exact supported suppress cooldown intervals, one entry per duration unit.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> FrequencyCapConstraints:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('mutable_fields',), ('supported_control_modes',), ('supported_per_units',), ('max_impressions_constraints',), ('window_constraints',), ('suppression_constraints',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'FrequencyCapConstraints requires at least one of these field groups: mutable_fields | supported_control_modes | supported_per_units | max_impressions_constraints | window_constraints | suppression_constraints'
        )

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 ext : ExtensionObject | None
var max_impressions_constraints : FrequencyCapImpressionConstraints | None
var model_config
var mutable_fields : list[FrequencyCapMutableField] | None
var supported_control_modes : list[FrequencyCapControlMode] | None
var supported_per_units : list[ReachUnit] | None
var suppression_constraints : list[FrequencyCapIntervalConstraints] | None
var window_constraints : list[FrequencyCapIntervalConstraints] | None

Inherited members

class FrequencyCapDurationUnit (*args, **kwds)
Expand source code
class FrequencyCapDurationUnit(StrEnum):
    seconds = 'seconds'
    minutes = 'minutes'
    hours = 'hours'
    days = 'days'
    campaign = 'campaign'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var campaign
var days
var hours
var minutes
var seconds
class FrequencyCapImpressionConstraints (**data: Any)
Expand source code
class FrequencyCapImpressionConstraints(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    minimum: Annotated[SchemaInt | None, Field(ge=1)] = None
    maximum: Annotated[SchemaInt | None, Field(ge=1)] = None
    allowed_values: Annotated[list[AllowedValue] | None, Field(min_length=1)] = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> FrequencyCapImpressionConstraints:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('allowed_values',), ('minimum', 'maximum'),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'FrequencyCapImpressionConstraints requires at least one of these field groups: allowed_values | minimum+maximum'
        )

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 allowed_values : list[AllowedValue] | None
var ext : ExtensionObject | None
var maximum : int | None
var minimum : int | None
var model_config

Inherited members

class FrequencyCapIntervalConstraints (**data: Any)
Expand source code
class FrequencyCapIntervalConstraints(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    unit: frequency_cap_duration_unit.FrequencyCapDurationUnit
    minimum_interval: Annotated[SchemaInt | None, Field(ge=1)] = None
    maximum_interval: Annotated[SchemaInt | None, Field(ge=1)] = None
    allowed_intervals: Annotated[list[AllowedInterval] | None, Field(min_length=1)] = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> FrequencyCapIntervalConstraints:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('allowed_intervals',), ('minimum_interval', 'maximum_interval'),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'FrequencyCapIntervalConstraints requires at least one of these field groups: allowed_intervals | minimum_interval+maximum_interval'
        )

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 allowed_intervals : list[AllowedInterval] | None
var ext : ExtensionObject | None
var maximum_interval : int | None
var minimum_interval : int | None
var model_config
var unit : FrequencyCapDurationUnit

Inherited members

class FrequencyCapRequirements (**data: Any)
Expand source code
class FrequencyCapRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mutable_fields: Annotated[
        list[frequency_cap_mutable_field.FrequencyCapMutableField] | None,
        Field(
            description='Require each listed logical field to be mutable after creation. Matches a product whose mutable_fields contains every listed value, or a product that omits mutable_fields, or legacy frequency_cap: true. A product declaring mutable_fields: [] is create-only and never matches a non-empty list.',
            min_length=1,
        ),
    ] = None
    supported_control_modes: Annotated[
        list[frequency_cap_control_mode.FrequencyCapControlMode] | None, Field(min_length=1)
    ] = None
    supported_per_units: Annotated[list[reach_unit.ReachUnit] | None, Field(min_length=1)] = None
    supported_window_units: Annotated[
        list[frequency_cap_duration_unit.FrequencyCapDurationUnit] | None,
        Field(
            description='Require each listed unit to be a supported max_impressions.window unit after seller-wide inheritance.',
            min_length=1,
        ),
    ] = None
    supported_suppression_units: Annotated[
        list[frequency_cap_duration_unit.FrequencyCapDurationUnit] | None,
        Field(
            description='Require each listed unit to be a supported suppress unit after seller-wide inheritance.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var model_config
var mutable_fields : list[FrequencyCapMutableField] | None
var supported_control_modes : list[FrequencyCapControlMode] | None
var supported_per_units : list[ReachUnit] | None
var supported_suppression_units : list[FrequencyCapDurationUnit] | None
var supported_window_units : list[FrequencyCapDurationUnit] | None

Inherited members

class Freshness (**data: Any)
Expand source code
class Freshness(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    generated_at: Annotated[
        AwareDatetime, Field(description='Server timestamp when this feed page was generated.')
    ]
    latest_event_created_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Newest event creation timestamp currently visible in the feed for the requested type filter. Null when no matching event exists inside retention.'
        ),
    ]
    lag_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Seconds between generated_at and latest_event_created_at. Null when no matching event exists.',
            ge=0,
        ),
    ]
    retention_days: Annotated[
        SchemaInt,
        Field(description='Number of days the registry retains feed cursors and events.', ge=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 generated_at : pydantic.types.AwareDatetime
var lag_seconds : int | None
var latest_event_created_at : pydantic.types.AwareDatetime | None
var model_config
var retention_days : int

Inherited members

class FuelType (*args, **kwds)
Expand source code
class FuelType(StrEnum):
    gasoline = 'gasoline'
    diesel = 'diesel'
    electric = 'electric'
    hybrid = 'hybrid'
    plug_in_hybrid = 'plug_in_hybrid'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var diesel
var electric
var gasoline
var hybrid
var plug_in_hybrid
class GBEnum (*args, **kwds)
Expand source code
class GBEnum(StrEnum):
    outward = 'outward'
    full = 'full'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var full
var outward
class GenerationContext (**data: Any)
Expand source code
class GenerationContext(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    context_type: Annotated[
        str | None,
        Field(
            description="Type of context that triggered generation (e.g., 'web_page', 'conversational', 'search', 'app', 'dooh')"
        ),
    ] = None
    artifact: Annotated[
        Artifact | None,
        Field(
            description='Reference to the content-standards artifact that provided the generation context. Links this variant to the specific piece of content (article, video, podcast segment, etc.) where the ad was placed.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 artifact : Artifact | None
var context_type : str | None
var ext : ExtensionObject | None
var model_config

Inherited members

class GenerationCredential (**data: Any)
Expand source code
class GenerationCredential(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    provider: Annotated[
        str,
        Field(
            description="LLM or generation service provider identifier (e.g., 'midjourney', 'elevenlabs', 'stability')"
        ),
    ]
    rights_key: Annotated[
        str,
        Field(
            description='Scoped API key or token for generating rights-cleared content. The provider validates this key at generation time to verify the caller is authorized.'
        ),
    ]
    uses: Annotated[
        list[right_use.RightUse],
        Field(description='Which rights uses this credential covers', min_length=1),
    ]
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='When this credential expires. Key lifetime is determined by the provider.'
        ),
    ] = None
    endpoint: Annotated[
        AnyUrl | None,
        Field(
            description="Provider API endpoint to use with this credential, if different from the provider's default"
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 endpoint : pydantic.networks.AnyUrl | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var model_config
var provider : str
var rights_key : str
var uses : list[RightUse]

Inherited members

class Geo (**data: Any)
Expand source code
class Geo(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    countries: Annotated[
        list[str] | None,
        Field(description='ISO 3166-1 alpha-2 country codes where ads will deliver.'),
    ] = None
    regions: Annotated[
        list[str] | None, Field(description='ISO 3166-2 subdivision codes where ads will deliver.')
    ] = 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 countries : list[str] | None
var model_config
var regions : list[str] | None

Inherited members

class GeoDeliveryMetrics (**data: Any)
Expand source code
class GeoDeliveryMetrics(DeliveryMetrics):
    geo_level: Annotated[
        geo_level_1.GeographicTargetingLevel,
        Field(description='Geographic level of this entry (country, region, metro, postal_area)'),
    ]
    system: Annotated[
        str | None,
        Field(
            description='Classification system for metro or postal_area levels. Metro rows use metro-system values. Native postal rows use country-local postal-system values with country; deprecated legacy postal rows may use legacy-postal-system values.'
        ),
    ] = None
    country: Annotated[
        str | None,
        Field(
            description='ISO 3166-1 alpha-2 country code for native postal_area rows.',
            pattern='^[A-Z]{2}$',
        ),
    ] = None
    geo_code: Annotated[
        str,
        Field(
            description="Geographic code within the level and system. Country: ISO 3166-1 alpha-2 ('US'). Region: ISO 3166-2 with country prefix ('US-CA'). Metro/postal: system-specific code ('501', '10001')."
        ),
    ]
    geo_name: Annotated[
        str | None,
        Field(
            description="Human-readable geographic name (e.g., 'United States', 'California', 'New York DMA')"
        ),
    ] = None
    impressions: Any
    spend: Any

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 country : str | None
var geo_code : str
var geo_level : GeographicTargetingLevel
var geo_name : str | None
var impressions : Any
var model_config
var spend : Any
var system : str | None

Inherited members

class GeoForecastDimension (**data: Any)
Expand source code
class GeoForecastDimension(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Annotated[Literal['geo'], Field(description='Dimension family discriminator.')] = 'geo'
    geo_level: Annotated[
        geo_level_1.GeographicTargetingLevel,
        Field(description='Geographic level for this forecast point.'),
    ]
    system: Annotated[
        str | None,
        Field(
            description="Classification system for metro or postal_area levels. Required when geo_level is 'metro' or 'postal_area'. Metro rows use metro-system enum values such as 'nielsen_dma'; native postal rows use country-local postal-system enum values such as 'zip' with country 'US'; deprecated legacy postal rows may use legacy-postal-system enum values such as 'us_zip'. Omit for country and region rows."
        ),
    ] = None
    country: Annotated[
        str | None,
        Field(
            description='ISO 3166-1 alpha-2 country code. Required for native postal_area rows and omitted for legacy postal rows, metro rows, country rows, and region rows.',
            pattern='^[A-Z]{2}$',
        ),
    ] = None
    geo_code: Annotated[
        str,
        Field(
            description="Geographic code within the level and system. Country: ISO 3166-1 alpha-2 ('US'). Region: ISO 3166-2 with country prefix ('US-CA'). Metro/postal: system-specific code ('501', '10001')."
        ),
    ]
    geo_name: Annotated[
        str | None,
        Field(
            description="Human-readable geographic name (e.g., 'United States', 'California', 'New York DMA')."
        ),
    ] = 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 country : str | None
var geo_code : str
var geo_level : GeographicTargetingLevel
var geo_name : str | None
var kind : Literal['geo']
var model_config
var system : str | None

Inherited members

class GeoMetro (**data: Any)
Expand source code
class GeoMetro(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    system: Annotated[
        metro_system.MetroAreaSystem,
        Field(description="Metro area classification system (e.g., 'nielsen_dma', 'uk_itl2')"),
    ]
    values: Annotated[
        list[str],
        Field(
            description="Metro codes within the system (e.g., ['501', '602'] for Nielsen DMAs)",
            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 model_config
var system : MetroAreaSystem
var values : list[str]

Inherited members

class GeoTargets (**data: Any)
Expand source code
class GeoTargets(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    countries: Annotated[
        list[Country] | None,
        Field(
            description="Countries where this offering is relevant. ISO 3166-1 alpha-2 codes (e.g., 'US', 'NL', 'DE').",
            min_length=1,
        ),
    ] = None
    regions: Annotated[
        list[Region] | None,
        Field(
            description="Regions or states where this offering is relevant. ISO 3166-2 subdivision codes (e.g., 'NL-NH', 'US-CA').",
            min_length=1,
        ),
    ] = None
    metros: Annotated[
        list[Metro] | None,
        Field(
            description='Metro areas where this offering is relevant. Each entry specifies the classification system and target values.',
            min_length=1,
        ),
    ] = None
    postal_areas: Annotated[
        list[postal_area.PostalArea] | None,
        Field(
            description='Postal areas where this offering is relevant. Prefer the native country + postal system form. Deprecated legacy country-fused postal-system tokens remain accepted for compatibility.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var countries : list[Country] | None
var metros : list[Metro] | None
var model_config
var postal_areas : list[PostalArea] | None
var regions : list[Region] | None

Inherited members

class GeographicBreakdownSupport (**data: Any)
Expand source code
class GeographicBreakdownSupport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    country: Annotated[
        StrictBool | None,
        Field(description='Supports country-level geo breakdown (ISO 3166-1 alpha-2)'),
    ] = None
    region: Annotated[
        StrictBool | None,
        Field(description='Supports region/state-level geo breakdown (ISO 3166-2)'),
    ] = None
    metro: Annotated[
        dict[metro_system.MetroAreaSystem, StrictBool] | None,
        Field(
            description='Metro area breakdown support. Keys are metro-system enum values; true means supported.'
        ),
    ] = None
    postal_area: Annotated[
        postal_area_support.PostalAreaSupport | None,
        Field(
            description='Postal area breakdown support. Prefer the native country-keyed map where each ISO 3166-1 alpha-2 country lists supported country-local postal systems. Deprecated legacy country-fused postal-system boolean maps remain accepted for compatibility.'
        ),
    ] = 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 country : bool | None
var metro : dict[MetroAreaSystem, bool] | None
var model_config
var postal_area : PostalAreaSupport | None
var region : bool | None

Inherited members

class GeographicPlaceArea (**data: Any)
Expand source code
class GeographicPlaceArea(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    country: Annotated[
        str,
        Field(
            description='ISO 3166-1 alpha-2 country code containing the place.',
            pattern='^[A-Z]{2}$',
        ),
    ]
    system: geo_place_system.GeographicPlaceIdentifierSystem
    system_version: Annotated[
        str | None,
        Field(
            description="Optional exact catalog version from the seller's declared supported_versions. When omitted, the seller applies catalog.current_version and MUST echo that version on persisted package state.",
            min_length=1,
        ),
    ] = None
    place_type: geo_place_type.GeographicPlaceType
    values: Annotated[
        list[Value],
        Field(
            description='Stable place identifiers in the declared system. Display names are not valid targeting values.',
            min_length=1,
        ),
    ]
    value_labels: Annotated[
        dict[str, str] | None,
        Field(
            description='Optional human-readable diagnostic labels keyed by identifiers present in values. Extra keys are a conformance error. Labels are non-authoritative and MUST NOT be used to resolve or apply targeting.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 country : str
var ext : ExtensionObject | None
var model_config
var place_type : GeographicPlaceType1 | GeographicPlaceType2
var system : GeographicPlaceIdentifierSystem1 | GeographicPlaceIdentifierSystem2
var system_version : str | None
var value_labels : dict[str, str] | None
var values : list[Value]

Inherited members

class GeographicPlaceCatalogCapability (**data: Any)
Expand source code
class GeographicPlaceCatalogCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    source: Annotated[
        AnyUrl | None,
        Field(
            description='Optional catalog dataset or derivative-source identifier. This records provenance/coverage and does not change the identifier namespace in system.'
        ),
    ] = None
    current_version: Annotated[
        str,
        Field(
            description='Version applied when a buyer omits system_version. Sellers MUST echo this version on persisted package state.',
            min_length=1,
        ),
    ]
    supported_versions: Annotated[
        list[SupportedVersion],
        Field(
            description='Exact catalog versions accepted for new targeting or target-changing updates. Must include current_version. Removing a version does not mutate or silently invalidate targets already pinned to it.',
            min_length=1,
        ),
    ]
    resolver: geo_place_resolver.GeographicPlaceResolver

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 current_version : str
var model_config
var resolver : GeographicPlaceResolver
var source : pydantic.networks.AnyUrl | None
var supported_versions : list[SupportedVersion]

Inherited members

class GeographicPlaceCatalogEntry (**data: Any)
Expand source code
class GeographicPlaceCatalogEntry(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    value: Annotated[
        str,
        Field(
            description='Stable identifier in the response system and system_version.', min_length=1
        ),
    ]
    country: Annotated[str, Field(pattern='^[A-Z]{2}$')]
    subdivision: Annotated[
        str | None,
        Field(
            description='ISO 3166-2 subdivision containing the place when the catalog has a subdivision mapping. Required by resolver semantics when the request constrained subdivision.',
            pattern='^[A-Z]{2}-[A-Z0-9]{1,3}$',
        ),
    ] = None
    place_type: geo_place_type.GeographicPlaceType
    label: Annotated[
        str,
        Field(
            description='Human-readable display label; never an authoritative targeting key.',
            min_length=1,
        ),
    ]
    canonical_name: Annotated[
        str,
        Field(
            description='Required fully qualified display name suitable for distinguishing same-named results.',
            min_length=1,
        ),
    ]
    parent_labels: Annotated[
        list[ParentLabel],
        Field(
            description='Ordered human-readable parent hierarchy for disambiguation only. Must include at least the containing country.',
            min_length=1,
        ),
    ]
    status: Status
    replaced_by_values: Annotated[
        list[ReplacedByValue] | None,
        Field(
            description='Replacement identifiers in the same system and response system_version.',
            min_length=1,
        ),
    ] = None
    valid_until: Annotated[
        AwareDatetime | None,
        Field(
            description='Known time after which the identifier must no longer be accepted for new targeting.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 canonical_name : str
var country : str
var ext : ExtensionObject | None
var label : str
var model_config
var parent_labels : list[ParentLabel]
var place_type : GeographicPlaceType1 | GeographicPlaceType2
var replaced_by_values : list[ReplacedByValue] | None
var status : Status
var subdivision : str | None
var valid_until : pydantic.types.AwareDatetime | None
var value : str

Inherited members

class GeographicPlaceIdentifierSystem1 (*args, **kwds)
Expand source code
class GeographicPlaceIdentifierSystem1(StrEnum):
    geonames = 'geonames'
    google_ads = 'google_ads'
    microsoft_ads = 'microsoft_ads'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var geonames
var google_ads
var microsoft_ads
class GeographicPlaceIdentifierSystem2 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class GeographicPlaceIdentifierSystem2(RootModel[AnyUrl]):
    root: Annotated[
        AnyUrl,
        Field(
            description='Collision-safe identifier namespace for geographic places. Registered tokens have protocol-defined semantics. Unregistered systems MUST use an absolute HTTPS URI controlled by the catalog owner; consumers compare URI systems as exact opaque strings.',
            examples=[
                'geonames',
                'google_ads',
                'microsoft_ads',
                'https://seller.example/geo/catalogs/places',
            ],
            title='Geographic Place Identifier System',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[AnyUrl]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : pydantic.networks.AnyUrl
class GeographicPlaceRequirement (**data: Any)
Expand source code
class GeographicPlaceRequirement(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    systems: Annotated[
        dict[geo_place_system.GeographicPlaceIdentifierSystem, CatalogRequirement],
        Field(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 model_config
var systems : dict[GeographicPlaceIdentifierSystem1 | GeographicPlaceIdentifierSystem2, CatalogRequirement]

Inherited members

class GeographicPlaceResolver (**data: Any)
Expand source code
class GeographicPlaceResolver(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    url: Annotated[
        AnyUrl,
        Field(
            description='HTTPS endpoint accepting the standard geo-place resolution query parameters.'
        ),
    ]
    auth: Annotated[
        Auth,
        Field(
            description="Authentication mode. seller_credentials means use the same authorization credentials as the seller's AdCP endpoint and is valid only for a same-origin resolver URL; credentials MUST NOT be forwarded cross-origin."
        ),
    ]
    protocol: Annotated[
        Literal['adcp_geo_place_resolver_v1'],
        Field(description='Resolver request/response contract version.'),
    ] = 'adcp_geo_place_resolver_v1'

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 auth : Auth
var model_config
var protocol : Literal['adcp_geo_place_resolver_v1']
var url : pydantic.networks.AnyUrl

Inherited members

class GeographicPlaceSystemSupport (**data: Any)
Expand source code
class GeographicPlaceSystemSupport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    countries: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[A-Z]{2}$')], list[geo_place_type.GeographicPlaceType]],
        Field(
            description='Supported place types keyed by ISO 3166-1 alpha-2 country. Only explicitly listed country/type pairs are supported.',
            min_length=1,
        ),
    ]
    catalog: geo_place_catalog_capability.GeographicPlaceCatalogCapability

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 catalog : GeographicPlaceCatalogCapability
var countries : dict[str, list[GeographicPlaceType1 | GeographicPlaceType2]]
var model_config

Inherited members

class GeographicPlaceType1 (*args, **kwds)
Expand source code
class GeographicPlaceType1(StrEnum):
    airport = 'airport'
    borough = 'borough'
    city = 'city'
    city_region = 'city_region'
    commune = 'commune'
    county = 'county'
    district = 'district'
    municipality = 'municipality'
    neighborhood = 'neighborhood'
    post_town = 'post_town'
    prefecture = 'prefecture'
    province = 'province'
    quarter = 'quarter'
    state = 'state'
    territory = 'territory'
    ward = 'ward'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var airport
var borough
var city
var city_region
var commune
var county
var district
var municipality
var neighborhood
var post_town
var prefecture
var province
var quarter
var state
var territory
var ward
class GeographicPlaceType2 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class GeographicPlaceType2(RootModel[AnyUrl]):
    root: Annotated[
        AnyUrl,
        Field(
            description='Canonical place classification. Registered tokens have protocol-defined meanings. Catalog-specific classifications without a registered mapping MUST use an absolute HTTPS URI controlled by the vocabulary owner; consumers compare URI types as exact opaque strings.',
            examples=[
                'city',
                'municipality',
                'borough',
                'neighborhood',
                'post_town',
                'city_region',
                'county',
                'https://seller.example/geo/place-types/trade-area',
            ],
            title='Geographic Place Type',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[AnyUrl]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : pydantic.networks.AnyUrl
class GeographicRegionRequirement (**data: Any)
Expand source code
class GeographicRegionRequirement(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    countries: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[A-Z]{2}$')], Countries | Countries1],
        Field(
            description='Required ISO subdivision support keyed by ISO 3166-1 alpha-2 country.',
            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 countries : dict[str, Countries | Countries1]
var model_config

Inherited members

class GeographicRegionSupport (**data: Any)
Expand source code
class GeographicRegionSupport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    countries: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[A-Z]{2}$')], Countries | Countries3],
        Field(
            description='Selectable ISO subdivision values keyed by ISO 3166-1 alpha-2 country.',
            min_length=1,
        ),
    ]
    catalog_version: Annotated[
        str | None,
        Field(
            description='Optional opaque ISO subdivision catalog or seller-mapping version that identifies the support snapshot. It is provenance, not part of subdivision identity.',
            min_length=1,
        ),
    ] = None
    as_of: Annotated[
        date | None,
        Field(
            description='Optional date on which the seller last validated this support declaration.'
        ),
    ] = None
    max_values_per_package: Annotated[
        SchemaInt | None,
        Field(
            description='Optional maximum number of region values selectable on one package.', ge=1
        ),
    ] = None
    max_packages: Annotated[
        SchemaInt | None,
        Field(
            description='Optional maximum number of independently region-targeted packages created from this configured product.',
            ge=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 as_of : datetime.date | None
var catalog_version : str | None
var countries : dict[str, Countries | Countries3]
var ext : ExtensionObject | None
var max_packages : int | None
var max_values_per_package : int | None
var model_config

Inherited members

class GetCreativeFeaturesSubmitted (**data: Any)
Expand source code
class GetCreativeFeaturesSubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal that discriminates this acknowledgement from terminal success and error responses.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='AdCP task handle used to poll get_task_status or correlate terminal webhook delivery. Distinct from evaluation_id.',
            min_length=1,
        ),
    ]
    evaluation_id: Annotated[
        str | None,
        Field(
            description='Provider-generated identity allocated when the evaluation is accepted. Optional in AdCP 3.x and required in AdCP 4.0. Providers SHOULD emit it in 3.x; when present, exact replays and the terminal result MUST carry this same value. Distinct from task_id and idempotency_key.',
            min_length=1,
        ),
    ] = None
    message: Annotated[
        str | None,
        Field(
            description='Optional human-readable explanation of why the evaluation is submitted. Plain text only; callers treat it as untrusted provider input.',
            max_length=2000,
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var evaluation_id : str | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class GetGeographicPlaceResolutionRequest (**data: Any)
Expand source code
class GetGeographicPlaceResolutionRequest(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    q: Annotated[
        str | None,
        Field(description='Unresolved place name or alias supplied by the user.', min_length=1),
    ] = None
    value: Annotated[
        str | None,
        Field(
            description='Existing identifier to look up in the requested/current catalog version for lifecycle refresh or replacement discovery. Mutually exclusive with q.',
            min_length=1,
        ),
    ] = None
    country: Annotated[
        str,
        Field(
            description='ISO 3166-1 alpha-2 country code used to disambiguate the query.',
            pattern='^[A-Z]{2}$',
        ),
    ]
    subdivision: Annotated[
        str | None,
        Field(
            description='Optional ISO 3166-2 subdivision constraint.',
            pattern='^[A-Z]{2}-[A-Z0-9]{1,3}$',
        ),
    ] = None
    place_type: geo_place_type.GeographicPlaceType | None = None
    system_version: Annotated[
        str | None,
        Field(description='Optional exact supported catalog version to search.', min_length=1),
    ] = None
    locale: Annotated[
        locale_tag.LanguageTag | None,
        Field(description='Optional BCP 47 language tag for returned labels.'),
    ] = None
    cursor: Annotated[str | None, Field(min_length=1)] = None
    limit: Annotated[SchemaInt | None, Field(ge=1, le=100)] = 20

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> GetGeographicPlaceResolutionRequest:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('q',), ('value',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'GetGeographicPlaceResolutionRequest requires at least one of these field groups: q | value'
        )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var country : str
var cursor : str | None
var limit : int | None
var locale : LanguageTag | None
var model_config
var place_type : GeographicPlaceType1 | GeographicPlaceType2 | None
var q : str | None
var subdivision : str | None
var system_version : str | None
var value : str | None

Inherited members

class GetGeographicPlaceResolutionResponse (**data: Any)
Expand source code
class GetGeographicPlaceResolutionResponse(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    request: Annotated[
        get_geo_place_resolution_request.GetGeographicPlaceResolutionRequest,
        Field(
            description='Exact normalized request represented by this page. Pagination responses repeat the original query fields and may carry the page cursor.'
        ),
    ]
    system: geo_place_system.GeographicPlaceIdentifierSystem
    system_version: Annotated[str, Field(min_length=1)]
    matches: list[geo_place_catalog_entry.GeographicPlaceCatalogEntry]
    next_cursor: Annotated[str | None, Field(min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var matches : list[GeographicPlaceCatalogEntry]
var model_config
var next_cursor : str | None
var request : GetGeographicPlaceResolutionRequest
var system : GeographicPlaceIdentifierSystem1 | GeographicPlaceIdentifierSystem2
var system_version : str

Inherited members

class GetProductsInputRequired (**data: Any)
Expand source code
class GetProductsInputRequired(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    reason: Annotated[
        Reason | None, Field(description='Reason code indicating why input is needed')
    ] = None
    partial_results: Annotated[
        list[product.Product] | None,
        Field(description='Partial product results that may help inform the clarification'),
    ] = None
    suggestions: Annotated[
        list[str] | None, Field(description='Suggested values or options for the required input')
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var partial_results : list[Product] | None
var reason : Reason | None
var suggestions : list[str] | None

Inherited members

class GetProductsSubmitted (**data: Any)
Expand source code
class GetProductsSubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose products array is issued in-line. See task-status.json for the full task-status enum.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='Task handle the buyer uses with get_task_status (or the legacy AdCP tasks/get alias), and that the seller references on push-notification callbacks. The products array is issued on the completion artifact, not here. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A Task id.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description="Optional human-readable explanation of why the task is submitted — e.g., 'Custom curation queued; typical turnaround 10–30 minutes.' Plain text only. Buyers MUST treat this as untrusted seller input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile seller may inject prompt-injection payloads aimed at the buyer's agent.",
            max_length=2000,
        ),
    ] = None
    estimated_completion: Annotated[
        AwareDatetime | None, Field(description='Estimated completion time for the search')
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories, governance observations). Terminal failures belong in the error branch, not here.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var estimated_completion : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class GetProductsWorking (**data: Any)
Expand source code
class GetProductsWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None,
        Field(description='Progress percentage of the search operation', ge=0.0, le=100.0),
    ] = None
    current_step: Annotated[
        str | None,
        Field(
            description="Current step in the search process (e.g., 'searching_inventory', 'validating_availability')"
        ),
    ] = None
    total_steps: Annotated[
        SchemaInt | None, Field(description='Total number of steps in the search process')
    ] = None
    step_number: Annotated[
        SchemaInt | None, Field(description='Current step number (1-indexed)')
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var current_step : str | None
var ext : ExtensionObject | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class GetSignalsSubmitted (**data: Any)
Expand source code
class GetSignalsSubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose signals array is issued in-line. See task-status.json for the full task-status enum.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='Task handle the caller uses with get_task_status (or the legacy AdCP tasks/get alias), and that the agent references on push-notification callbacks. The signals array is issued on the completion artifact, not here. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A Task id.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description="Optional human-readable explanation of why the task is submitted — e.g., 'Provider discovery queued; typical turnaround 10-30 minutes.' Plain text only. Callers MUST treat this as untrusted agent input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile agent may inject prompt-injection payloads aimed at the caller's agent.",
            max_length=2000,
        ),
    ] = None
    estimated_completion: Annotated[
        AwareDatetime | None,
        Field(description='Estimated completion time for the signal discovery task.'),
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories or partial provider unavailability). Terminal failures belong in the error branch, not here.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var estimated_completion : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class GetSignalsWorking (**data: Any)
Expand source code
class GetSignalsWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None,
        Field(
            description='Progress percentage of the signal discovery operation.', ge=0.0, le=100.0
        ),
    ] = None
    current_step: Annotated[
        str | None,
        Field(
            description='Current step in the signal discovery process, such as `querying_providers`, `ranking_signals`, or `checking_deployments`.'
        ),
    ] = None
    total_steps: Annotated[
        SchemaInt | None,
        Field(description='Total number of steps in the signal discovery process.'),
    ] = None
    step_number: Annotated[
        SchemaInt | None, Field(description='Current step number (1-indexed).')
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var current_step : str | None
var ext : ExtensionObject | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class GoldenVectors (**data: Any)
Expand source code
class GoldenVectors(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    empty_report: Annotated[EmptyReport, Field(title='EmptyReportGoldenVector')]
    ordering_encoding: Annotated[OrderingEncoding, Field(title='OrderingEncodingGoldenVector')]
    additional: list[AdditionalItem] | 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 additional : list[AdditionalItem] | None
var empty_report : EmptyReport
var model_config
var ordering_encoding : OrderingEncoding

Inherited members

class GopType (*args, **kwds)
Expand source code
class GopType(StrEnum):
    closed = 'closed'
    open = 'open'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var closed
var open
class GovernanceAgent (**data: Any)
Expand source code
class GovernanceAgent(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    url: Annotated[AnyUrl, Field(description='Governance agent endpoint URL. Must use HTTPS.')]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var url : pydantic.networks.AnyUrl

Inherited members

class GradingProfile (*args, **kwds)
Expand source code
class GradingProfile(StrEnum):
    legacy = 'legacy'
    spec = 'spec'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var legacy
var spec
class GrantStatus (*args, **kwds)
Expand source code
class GrantStatus(StrEnum):
    active = 'active'
    paused = 'paused'
    revoked = 'revoked'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var active
var paused
var revoked
class HistoryItem (**data: Any)
Expand source code
class HistoryItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    timestamp: Annotated[AwareDatetime, Field(description='When this exchange occurred (ISO 8601)')]
    type: Annotated[
        Type, Field(description='Whether this was a request from client or response from server')
    ]
    data: Annotated[dict[str, Any], Field(description='The full request or response payload')]

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 data : dict[str, typing.Any]
var model_config
var timestamp : pydantic.types.AwareDatetime
var type : Type

Inherited members

class HotelItem (**data: Any)
Expand source code
class HotelItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    hotel_id: Annotated[
        str,
        Field(
            description='Unique identifier for this property. Used to match remarketing events and inventory feeds to the correct hotel.'
        ),
    ]
    name: Annotated[
        str,
        Field(description="Property name (e.g., 'Grand Hotel Amsterdam', 'Seaside Resort & Spa')."),
    ]
    description: Annotated[
        str | None, Field(description='Property description highlighting features and location.')
    ] = None
    location: Annotated[Location, Field(description='Geographic coordinates of the property.')]
    address: Annotated[
        Address | None, Field(description='Structured address for display and geocoding.')
    ] = None
    star_rating: Annotated[
        SchemaInt | None, Field(description='Official star rating (1–5).', ge=1, le=5)
    ] = None
    price: Annotated[
        price_1.Price | None,
        Field(description="Nightly rate or starting price. Use period 'night' for nightly rates."),
    ] = None
    image_url: Annotated[AnyUrl | None, Field(description='Primary property image URL.')] = None
    url: Annotated[AnyUrl | None, Field(description='Property landing page or booking URL.')] = None
    phone: Annotated[str | None, Field(description='Property phone number in E.164 format.')] = None
    amenities: Annotated[
        list[str] | None,
        Field(
            description="Property amenities (e.g., 'pool', 'wifi', 'spa', 'parking', 'restaurant').",
            min_length=1,
        ),
    ] = None
    check_in_time: Annotated[
        str | None,
        Field(
            description="Standard check-in time in HH:MM format (e.g., '15:00').",
            pattern='^[0-2][0-9]:[0-5][0-9]$',
        ),
    ] = None
    check_out_time: Annotated[
        str | None,
        Field(
            description="Standard check-out time in HH:MM format (e.g., '11:00').",
            pattern='^[0-2][0-9]:[0-5][0-9]$',
        ),
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering and targeting (e.g., 'boutique', 'family', 'business', 'luxury').",
            min_length=1,
        ),
    ] = None
    valid_from: Annotated[
        date | None,
        Field(
            description="Date from which this item is available or this rate applies (ISO 8601, e.g., '2025-03-01'). Used for seasonal availability windows in feed imports."
        ),
    ] = None
    valid_to: Annotated[
        date | None,
        Field(
            description="Date until which this item is available or this rate applies (ISO 8601, e.g., '2025-09-30'). Used for seasonal availability windows in feed imports."
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this hotel. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (16:9 hero images), 'images_vertical' (9:16 for Snap, Stories), 'images_square' (1:1), 'logo'. Enables formats to declare typed image requirements that map unambiguously to the right asset regardless of platform.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 address : Address | None
var amenities : list[str] | None
var assets : list[OfferingAssetGroup] | None
var check_in_time : str | None
var check_out_time : str | None
var description : str | None
var ext : ExtensionObject | None
var hotel_id : str
var image_url : pydantic.networks.AnyUrl | None
var location : Location
var model_config
var name : str
var phone : str | None
var price : Price | None
var star_rating : int | None
var tags : list[str] | None
var url : pydantic.networks.AnyUrl | None
var valid_from : datetime.date | None
var valid_to : datetime.date | None

Inherited members

class HtmlAssetRequirements (**data: Any)
Expand source code
class HtmlAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_file_size_kb: Annotated[
        SchemaInt | None,
        Field(description='Maximum file size in kilobytes for the HTML asset', ge=1),
    ] = None
    sandbox: Annotated[
        Sandbox | None,
        Field(
            description="Sandbox environment the HTML must be compatible with. 'none' = direct DOM access, 'iframe' = standard iframe isolation, 'safeframe' = IAB SafeFrame container, 'fencedframe' = Privacy Sandbox fenced frame"
        ),
    ] = Sandbox.none
    external_resources_allowed: Annotated[
        StrictBool | None,
        Field(
            description='Whether the HTML creative can load external resources (scripts, images, fonts, etc.). When false, all resources must be inlined or bundled.'
        ),
    ] = None
    allowed_external_domains: Annotated[
        list[str] | None,
        Field(
            description='List of domains the HTML creative may reference for external resources. Only applicable when external_resources_allowed is true.'
        ),
    ] = 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 allowed_external_domains : list[str] | None
var external_resources_allowed : bool | None
var max_file_size_kb : int | None
var model_config
var sandbox : Sandbox | None

Inherited members

class HttpMethod (*args, **kwds)
Expand source code
class HttpMethod(StrEnum):
    GET = 'GET'
    POST = 'POST'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var GET
var POST
class IanaTimezoneIdentifier (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class IanaTimezoneIdentifier(ScalarStr):
    __slots__ = ()
    _constraints = {
        'max_length': 255,
        'min_length': 1,
        'pattern': '^[A-Za-z0-9._+-]+(?:/[A-Za-z0-9._+-]+)*$',
    }
    _json_schema_extra = {
        'description': "Concrete timezone identifier in the implementation's supported IANA Time Zone Database, such as America/New_York, CET, or UTC.",
        'title': 'IANA Timezone Identifier',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class IanaTimezones (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class IanaTimezones(RootModel[list[iana_timezone.IanaTimezoneIdentifier]]):
    root: Annotated[
        list[iana_timezone.IanaTimezoneIdentifier],
        Field(
            description="Concrete IANA timezone identifiers accepted by this product. true means every identifier valid in the seller's supported IANA TZDB; an array is the exact supported subset. Required when timezone_modes includes iana and forbidden otherwise.",
            min_length=1,
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[list[IanaTimezoneIdentifier]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[IanaTimezoneIdentifier]
class IfNotCovered (*args, **kwds)
Expand source code
class IfNotCovered(StrEnum):
    exclude = 'exclude'
    include = 'include'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var exclude
var include
class ImageAssetRequirements (**data: Any)
Expand source code
class ImageAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    min_width: Annotated[
        StrictFloat | None,
        Field(
            description='Minimum width. Interpretation depends on unit (default: pixels). For exact dimensions, set min_width = max_width.',
            gt=0.0,
        ),
    ] = None
    max_width: Annotated[
        StrictFloat | None,
        Field(
            description='Maximum width. Interpretation depends on unit (default: pixels). For exact dimensions, set min_width = max_width.',
            gt=0.0,
        ),
    ] = None
    min_height: Annotated[
        StrictFloat | None,
        Field(
            description='Minimum height. Interpretation depends on unit (default: pixels). For exact dimensions, set min_height = max_height.',
            gt=0.0,
        ),
    ] = None
    max_height: Annotated[
        StrictFloat | None,
        Field(
            description='Maximum height. Interpretation depends on unit (default: pixels). For exact dimensions, set min_height = max_height.',
            gt=0.0,
        ),
    ] = None
    pixel_ratios: Annotated[
        list[PixelRatio] | None,
        Field(
            description='Accepted intrinsic-pixel densities for this image slot. One submitted image matching any listed ratio satisfies the slot; the array does not require one asset per ratio. Absence imposes no density constraint beyond the existing dimension requirements.',
            min_length=1,
        ),
    ] = None
    parameters_from_format_id: Annotated[
        StrictBool | None,
        Field(
            description="When true on a legacy template format, logical width, logical height, and pixel ratio are supplied by the parameterized format_id. The image asset's intrinsic dimensions MUST equal logical dimensions multiplied by pixel_ratio (which defaults to 1 when omitted)."
        ),
    ] = None
    unit: Annotated[
        dimension_unit.DimensionUnit | None,
        Field(
            description="Unit of measurement for width/height values. Defaults to 'px' when absent. Print formats use 'inches' or 'cm'."
        ),
    ] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description="Required aspect ratio (e.g., '16:9', '1:1', '1.91:1')",
            pattern='^\\d+(\\.\\d+)?:\\d+(\\.\\d+)?$',
        ),
    ] = None
    formats: Annotated[list[Format] | None, Field(description='Accepted image file formats')] = None
    min_dpi: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum resolution in dots per inch. Always in DPI regardless of the dimension unit. Standard print requires 300 DPI, newspaper 150 DPI.',
            ge=1,
        ),
    ] = None
    bleed: Annotated[
        Bleed | Bleed1 | None,
        Field(
            description='Required bleed area beyond the trim size. The submitted image must be larger than the declared dimensions: total width = trim width + left bleed + right bleed, total height = trim height + top bleed + bottom bleed. For uniform bleed: total = trim + (2 * uniform). Uses the same unit as the parent dimensions.'
        ),
    ] = None
    color_space: Annotated[
        ColorSpace | None, Field(description='Required color space. Print typically requires CMYK.')
    ] = None
    max_file_size_kb: Annotated[
        SchemaInt | None, Field(description='Maximum file size in kilobytes', ge=1)
    ] = None
    transparency_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether the image must support transparency (requires PNG, WebP, or GIF)'
        ),
    ] = None
    animation_allowed: Annotated[
        StrictBool | None,
        Field(description='Whether animated images (GIF, animated WebP) are accepted'),
    ] = None
    max_animation_duration_ms: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum animation duration in milliseconds (if animation_allowed is true)',
            ge=0,
        ),
    ] = None
    max_weight_grams: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum weight in grams for the finished physical piece (print inserts, flyers). Affects postage calculations and production constraints. Only applicable to print channels.',
            gt=0,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var animation_allowed : bool | None
var aspect_ratio : str | None
var bleed : Bleed | Bleed1 | None
var color_space : ColorSpace | None
var formats : list[Format] | None
var max_animation_duration_ms : int | None
var max_file_size_kb : int | None
var max_height : float | None
var max_weight_grams : int | None
var max_width : float | None
var min_dpi : int | None
var min_height : float | None
var min_width : float | None
var model_config
var parameters_from_format_id : bool | None
var pixel_ratios : list[PixelRatio] | None
var transparency_required : bool | None
var unit : DimensionUnit | None

Inherited members

class ImageDecoration (**data: Any)
Expand source code
class ImageDecoration(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['image'] = 'image'
    layer: Layer
    bounds: Rectangle
    image_ref: ImageRef
    fit: Fit

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 bounds : Rectangle
var fit : Fit
var image_ref : ImageRef
var kind : Literal['image']
var layer : Layer
var model_config

Inherited members

class ImageRef (**data: Any)
Expand source code
class ImageRef(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    uri: Annotated[
        AnyUrl,
        Field(
            description='Untrusted image asset. Fetch with public-address-only SSRF protection, no redirects, DNS pinning, and body/time limits; do not attach ambient credentials.'
        ),
    ]
    digest: Annotated[
        str,
        Field(
            description='SHA-256 digest of the exact image bytes. Consumers MUST fail closed on mismatch.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]

    @field_validator('uri')
    @classmethod
    def _require_https_uri(cls, value: AnyUrl) -> AnyUrl:
        if value.scheme != 'https':
            raise ValueError('uri must use https')
        return value

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var digest : str
var model_config
var uri : pydantic.networks.AnyUrl

Inherited members

class Immutability (*args, **kwds)
Expand source code
class Immutability(StrEnum):
    immutable_location = 'immutable_location'
    native_version = 'native_version'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var immutable_location
var native_version
class Impact (**data: Any)
Expand source code
class Impact(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    area: Area
    effect: Effect
    reason: Annotated[str | None, Field(max_length=1000, min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var area : Area
var effect : Effect
var model_config
var reason : str | None

Inherited members

class Impairment (**data: Any)
Expand source code
class Impairment(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    impairment_id: Annotated[
        str,
        Field(
            description="Stable identifier for this impairment, used as the notification_id when the impairment fires via webhook. Stable across re-emissions of the same open impairment (e.g., the seller re-fires after the buyer's receiver was down) and across the closing fire that signals resolution. A new impairment for the same resource_id after closure receives a new impairment_id. Distinct from the per-fire idempotency_key issued at the webhook transport layer — see snapshot-and-log Rule 1. Receivers correlate webhook fires to current impairments[] state by impairment_id; receivers suppress duplicate transport-layer retries by idempotency_key. Seeing the same impairment_id with different idempotency_keys is a re-emission signal, not a retry — the buyer should treat it as a notice that something may have been missed."
        ),
    ]
    resource_type: Annotated[
        ResourceType,
        Field(
            description="The kind of upstream dependency that transitioned to an offline state. Values are drawn from the x-entity vocabulary (see core/x-entity-types.json) and identify a buyer-referenced object with its own lifecycle that the seller can take offline. This is the subset of x-entity types for which a media buy's serving depends on the resource — not a new typology, just the impairment-relevant slice."
        ),
    ]
    resource_id: Annotated[
        str,
        Field(
            description="Seller's identifier for the specific resource that transitioned. References the same id space as the corresponding sync_/list_ task responses (e.g., audience_id, creative_id)."
        ),
    ]
    package_ids: Annotated[
        list[str],
        Field(
            description="Packages within this media buy whose delivery is degraded by the impairment. MUST list at least one package — cosmetic effects that do not degrade any package's ability to serve MUST NOT be reported as impairments.",
            min_length=1,
        ),
    ]
    transition: Annotated[
        Transition,
        Field(description='The resource-level status transition that triggered this impairment.'),
    ]
    reason_code: Annotated[
        impairment_reason_code.ImpairmentReasonCode,
        Field(
            description='Categorical reason for the offline transition. Drives buyer-side remediation logic.'
        ),
    ]
    reason: Annotated[
        str | None,
        Field(
            description='Human-readable explanation. Supplements reason_code with seller-specific detail.',
            max_length=500,
        ),
    ] = None
    observed_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller observed the resource transition to its offline state.'
        ),
    ]
    remediation: Annotated[
        str | None,
        Field(
            description='Action the buyer can take to clear the impairment, if any. Free text. Absent when no buyer-side remediation is possible (e.g., seller-initiated withdrawal pending re-publication).',
            max_length=500,
        ),
    ] = 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 impairment_id : str
var model_config
var observed_at : pydantic.types.AwareDatetime
var package_ids : list[str]
var reason : str | None
var reason_code : ImpairmentReasonCode
var remediation : str | None
var resource_id : str
var resource_type : ResourceType
var transition : Transition

Inherited members

class Indicator (**data: Any)
Expand source code
class Indicator(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: indicator_type.IndicatorType
    detected_at: Annotated[
        AwareDatetime | None,
        Field(
            description='When the seller first detected the current uninterrupted occurrence of this indicator. Keep this value stable while the condition remains present. If the condition clears and is later detected again, use the new detection time. Optional because some upstream platforms expose current assessments without an original detection timestamp.'
        ),
    ] = None
    scope: Annotated[
        list[indicator_scope.IndicatorScope] | None,
        Field(
            description='Optional narrower publisher or placement scope within the enclosing media buy, package, or package–creative assignment. Omit only when the seller evaluated and asserts the indicator across the whole enclosing resource/relationship. When partial indicators_evaluated_scope is declared, every returned indicator MUST include scope and every entry MUST fall within that coverage. This is scope, not source: the responding seller remains the source.',
            min_length=1,
        ),
    ] = None
    ext: Annotated[
        ext_1.ExtensionObject | None,
        Field(
            description='Seller- or provider-specific detail such as scores, thresholds, evaluation windows, methodology identifiers, or upstream attribution. Core consumers must not need ext to understand the broad meaning of type.'
        ),
    ] = 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 detected_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var model_config
var scope : list[IndicatorScope] | None
var type : IndicatorType

Inherited members

class IndicatorBearingResourceState (**data: Any)
Expand source code
class IndicatorBearingResourceState(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    indicators: Annotated[
        list[indicator.Indicator] | None,
        Field(
            description='Current seller assertions for the indicator types and publisher/placement coverage named by the sibling evaluation fields. Omitted means unknown or not evaluated. A present empty array means evaluated with no current assertion for indicator_types_evaluated in the evaluated scope.'
        ),
    ] = None
    indicator_types_evaluated: Annotated[
        list[indicator_type.IndicatorType] | None,
        Field(
            description='Indicator types covered by this snapshot. Required whenever indicators is present. Types omitted from this list remain unknown even when indicators is empty. Every returned indicator.type MUST appear in this list.',
            min_length=1,
        ),
    ] = None
    indicators_as_of: Annotated[
        AwareDatetime | None,
        Field(
            description='When the seller completed this evaluation. Required whenever indicators is present, including an empty array. State changes require a strictly newer timestamp; equal-timestamp conflicts are invalid and buyers retain stored state.'
        ),
    ] = None
    indicators_evaluated_scope: Annotated[
        list[indicator_scope.IndicatorScope] | None,
        Field(
            description='Optional publisher or placement coverage for this evaluation. Omit when the named indicator types were evaluated across the whole enclosing resource or relationship. Unlisted scopes remain unknown. When present, every returned indicator MUST include scope and every scope entry MUST be contained by this coverage.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var indicator_types_evaluated : list[IndicatorType] | None
var indicators : list[Indicator] | None
var indicators_as_of : pydantic.types.AwareDatetime | None
var indicators_evaluated_scope : list[IndicatorScope] | None
var model_config

Inherited members

class IndicatorScope (**data: Any)
Expand source code
class IndicatorScope(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description="Domain where the publisher's adagents.json is hosted.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    placement_id: Annotated[
        str | None,
        Field(
            description='Optional placement ID within publisher_domain. Omit to scope the assertion or evaluation to all delivery for the publisher in the enclosing object.'
        ),
    ] = 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 model_config
var placement_id : str | None
var publisher_domain : str

Inherited members

class IndicatorsChangedWebhook (**data: Any)
Expand source code
class IndicatorsChangedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Random fire identifier reused across retries. Receivers dedupe within the authenticated sender scope.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Stable identity for this logical snapshot change across re-emissions. A later semantic change receives a new value.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Literal['indicators.changed'] = 'indicators.changed'
    fired_at: AwareDatetime
    subscriber_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    account_id: str
    relationship_kind: Annotated[
        RelationshipKind, Field(description='Identifies which indicator-bearing snapshot changed.')
    ]
    media_buy_id: str
    package_id: str | None = None
    creative_id: str | None = None
    change_kind: Annotated[
        ChangeKind,
        Field(
            description='Coarse invalidation reason. Buyers MUST reread rather than applying this value as state. invalidated is emitted when a material creative-content update retires the prior evaluation and the relationship becomes unknown until reevaluated. assignment_removed is emitted to indicator subscribers when deletion retires keys for a package–creative relationship.'
        ),
    ]
    changed_indicator_types: Annotated[
        list[indicator_type.IndicatorType],
        Field(
            description='Types known to be affected. This is a reread hint, not a complete current set.',
            min_length=1,
        ),
    ]
    observed_at: Annotated[
        AwareDatetime, Field(description='When the seller observed the semantic snapshot change.')
    ]
    ext: ext_1.ExtensionObject | 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 account_id : str
var change_kind : ChangeKind
var changed_indicator_types : list[IndicatorType]
var creative_id : str | None
var ext : ExtensionObject | None
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var media_buy_id : str
var model_config
var notification_id : str
var notification_type : Literal['indicators.changed']
var observed_at : pydantic.types.AwareDatetime
var package_id : str | None
var relationship_kind : RelationshipKind
var subscriber_id : str

Inherited members

class IndustryIdentifier (**data: Any)
Expand source code
class IndustryIdentifier(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: creative_identifier_type.CreativeIdentifierType
    value: Annotated[
        str,
        Field(
            description="The identifier value (e.g., 'ABCD1234000H' for Ad-ID). Preserve the value exactly as the traffic or clearance system expects it.",
            max_length=64,
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var type : CreativeIdentifierType
var value : str

Inherited members

class Input (**data: Any)
Expand source code
class Input(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    name: Annotated[str, Field(description='Human-readable name for this preview variant')]
    macros: Annotated[
        dict[str, str] | None, Field(description='Macro values to apply for this preview')
    ] = None
    context_description: Annotated[
        str | None,
        Field(description='Natural language description of the context for AI-generated content'),
    ] = 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 context_description : str | None
var macros : dict[str, str] | None
var model_config
var name : str

Inherited members

class InputFormat1 (**data: Any)
Expand source code
class InputFormat1(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image'] = 'image'
    params: image.CanonicalFormatImage

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImage
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat10 (**data: Any)
Expand source code
class InputFormat10(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['sponsored_placement'] = 'sponsored_placement'
    params: sponsored_placement.CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['sponsored_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat11 (**data: Any)
Expand source code
class InputFormat11(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['native_in_feed'] = 'native_in_feed'
    params: native_in_feed.CanonicalFormatNativeInFeed

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['native_in_feed']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatNativeInFeed
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat12 (**data: Any)
Expand source code
class InputFormat12(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['responsive_creative'] = 'responsive_creative'
    params: responsive_creative.CanonicalFormatResponsiveCreative

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['responsive_creative']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatResponsiveCreative
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat13 (**data: Any)
Expand source code
class InputFormat13(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['agent_placement'] = 'agent_placement'
    params: agent_placement.CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['agent_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat14 (**data: Any)
Expand source code
class InputFormat14(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['seller_rendered_stateful_display'] = 'seller_rendered_stateful_display'
    params: seller_rendered_stateful_display.CanonicalFormatSellerRenderedStatefulDisplay

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['seller_rendered_stateful_display']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSellerRenderedStatefulDisplay
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat15 (**data: Any)
Expand source code
class InputFormat15(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['coordinated_placements'] = 'coordinated_placements'
    params: coordinated_placements.CanonicalFormatCoordinatedPlacements

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['coordinated_placements']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatCoordinatedPlacements
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat16 (**data: Any)
Expand source code
class InputFormat16(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['custom'] = 'custom'
    params: Annotated[
        dict[str, Any],
        Field(
            description="Custom shape's params. Validated against the schema fetched from `format_schema.uri` at the cached `format_schema.digest`."
        ),
    ]

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['custom']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : dict[str, typing.Any]
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat17 (**data: Any)
Expand source code
class InputFormat17(AdCPBaseModel):
    pass

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 model_config

Inherited members

class InputFormat18 (**data: Any)
Expand source code
class InputFormat18(InputFormat1, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat19 (**data: Any)
Expand source code
class InputFormat19(InputFormat2, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat2 (**data: Any)
Expand source code
class InputFormat2(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['html5'] = 'html5'
    params: html5.CanonicalFormatHtml5Banner

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['html5']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHtml5Banner
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat20 (**data: Any)
Expand source code
class InputFormat20(InputFormat3, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat21 (**data: Any)
Expand source code
class InputFormat21(InputFormat4, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat22 (**data: Any)
Expand source code
class InputFormat22(InputFormat5, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat23 (**data: Any)
Expand source code
class InputFormat23(InputFormat6, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat24 (**data: Any)
Expand source code
class InputFormat24(InputFormat7, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat25 (**data: Any)
Expand source code
class InputFormat25(InputFormat8, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat26 (**data: Any)
Expand source code
class InputFormat26(InputFormat9, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat27 (**data: Any)
Expand source code
class InputFormat27(InputFormat10, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat28 (**data: Any)
Expand source code
class InputFormat28(InputFormat11, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat29 (**data: Any)
Expand source code
class InputFormat29(InputFormat12, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat3 (**data: Any)
Expand source code
class InputFormat3(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['display_tag'] = 'display_tag'
    params: display_tag.CanonicalFormatDisplayTag

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['display_tag']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDisplayTag
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat30 (**data: Any)
Expand source code
class InputFormat30(InputFormat13, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat31 (**data: Any)
Expand source code
class InputFormat31(InputFormat14, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat32 (**data: Any)
Expand source code
class InputFormat32(InputFormat15, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat33 (**data: Any)
Expand source code
class InputFormat33(InputFormat16, InputFormat17):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class InputFormat4 (**data: Any)
Expand source code
class InputFormat4(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image_carousel'] = 'image_carousel'
    params: image_carousel.CanonicalFormatImageCarousel

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image_carousel']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImageCarousel
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat5 (**data: Any)
Expand source code
class InputFormat5(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_hosted'] = 'video_hosted'
    params: video_hosted.CanonicalFormatHostedVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat6 (**data: Any)
Expand source code
class InputFormat6(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_vast'] = 'video_vast'
    params: video_vast.CanonicalFormatVastVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat7 (**data: Any)
Expand source code
class InputFormat7(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_hosted'] = 'audio_hosted'
    params: audio_hosted.CanonicalFormatHostedAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat8 (**data: Any)
Expand source code
class InputFormat8(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_vast'] = 'audio_vast'
    params: audio_vast.CanonicalFormatVastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InputFormat9 (**data: Any)
Expand source code
class InputFormat9(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_daast'] = 'audio_daast'
    params: audio_daast.CanonicalFormatDaastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_daast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDaastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class InsertionOrder (**data: Any)
Expand source code
class InsertionOrder(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    io_id: Annotated[
        str,
        Field(
            description='Unique identifier for this insertion order. Referenced by io_acceptance on create_media_buy.',
            max_length=255,
        ),
    ]
    terms: Annotated[
        Terms | None,
        Field(
            description='Summary fields echoed from the committed proposal for agent verification. Buyer agents use these to confirm the IO matches what was negotiated before a human signs. These are read-only summaries, not negotiation surfaces — deal terms live on products and packages.'
        ),
    ] = None
    terms_url: Annotated[
        AnyUrl | None,
        Field(
            description='URL to a human-readable document containing the full insertion order terms'
        ),
    ] = None
    signing_url: Annotated[
        AnyUrl | None,
        Field(
            description='URL to an electronic signing service (e.g., DocuSign) for human signature workflows. When present, a human must sign before the buyer agent can proceed with create_media_buy.'
        ),
    ] = None
    requires_signature: Annotated[
        StrictBool,
        Field(
            description='Whether the buyer must accept this IO before creating a media buy. When true, create_media_buy requires an io_acceptance referencing this io_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var io_id : str
var model_config
var requires_signature : bool
var signing_url : pydantic.networks.AnyUrl | None
var terms : Terms | None
var terms_url : pydantic.networks.AnyUrl | None

Inherited members

class Installment (**data: Any)
Expand source code
class Installment(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    installment_id: Annotated[
        str, Field(description='Unique identifier for this installment within the collection')
    ]
    collection_ref: Annotated[
        collection_ref_1.CollectionReference | None,
        Field(
            description='Canonical parent collection identity. Products spanning multiple collections or publisher namespaces MUST use this field.'
        ),
    ] = None
    collection_id: Annotated[
        str | None,
        Field(
            deprecated=True,
            description='Deprecated publisher-domain-free parent collection shorthand. Use collection_ref. It is unambiguous only when the enclosing product addresses one publisher namespace.',
        ),
    ] = None
    name: Annotated[str | None, Field(description='Installment title')] = None
    season: Annotated[
        str | None, Field(description="Season identifier (e.g., '1', '2024', 'spring_2026')")
    ] = None
    installment_number: Annotated[
        str | None, Field(description="Installment number within the season (e.g., '3', '47')")
    ] = None
    scheduled_at: Annotated[
        AwareDatetime | None, Field(description='When the installment airs or publishes (ISO 8601)')
    ] = None
    status: Annotated[
        installment_status.InstallmentStatus | None,
        Field(description='Lifecycle status of the installment'),
    ] = None
    duration_seconds: Annotated[
        SchemaInt | None, Field(description='Expected duration of the installment in seconds', ge=0)
    ] = None
    flexible_end: Annotated[
        StrictBool | None,
        Field(description='Whether the end time is approximate (live events, sports)'),
    ] = None
    valid_until: Annotated[
        AwareDatetime | None,
        Field(
            description='When this installment data expires and should be re-queried. Agents should re-query before committing budget to products with tentative installments.'
        ),
    ] = None
    content_rating: Annotated[
        content_rating_1.ContentRating | None,
        Field(
            description="Installment-specific content rating. Overrides the collection's baseline content_rating when present."
        ),
    ] = None
    topics: Annotated[
        list[str] | None,
        Field(
            description="Content topics for this installment. Uses the same taxonomy as the collection's genre_taxonomy when present. Enables installment-level brand safety evaluation beyond content_rating."
        ),
    ] = None
    special: Annotated[
        special_1.Special | None,
        Field(
            description='Installment-specific event context. When present, this installment is anchored to a real-world event. Overrides the collection-level special when present.'
        ),
    ] = None
    guest_talent: Annotated[
        list[talent.Talent] | None,
        Field(
            description="Installment-specific guests and talent. Additive to the collection's recurring talent."
        ),
    ] = None
    ad_inventory: Annotated[
        ad_inventory_config.AdInventoryConfiguration | None,
        Field(
            description='Break-based ad inventory for this installment. For non-break formats (host reads, integrations), use product placements.'
        ),
    ] = None
    deadlines: Annotated[
        installment_deadlines.InstallmentDeadlines | None,
        Field(
            description='Booking, cancellation, and material submission deadlines for this installment. Present when the installment has time-sensitive inventory that requires advance commitment or material delivery.'
        ),
    ] = None
    derivative_of: Annotated[
        DerivativeOf | None,
        Field(
            description='When this installment is a clip, highlight, or recap derived from a full installment. The source installment_id must reference an installment within the same response.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 ad_inventory : AdInventoryConfiguration | None
var collection_id : str | None
var collection_ref : CollectionReference | None
var content_rating : ContentRating | None
var deadlines : InstallmentDeadlines | None
var derivative_of : DerivativeOf | None
var duration_seconds : int | None
var ext : ExtensionObject | None
var flexible_end : bool | None
var guest_talent : list[Talent] | None
var installment_id : str
var installment_number : str | None
var model_config
var name : str | None
var scheduled_at : pydantic.types.AwareDatetime | None
var season : str | None
var special : Special | None
var status : InstallmentStatus | None
var topics : list[str] | None
var valid_until : pydantic.types.AwareDatetime | None

Inherited members

class InstallmentDeadlines (**data: Any)
Expand source code
class InstallmentDeadlines(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    booking_deadline: Annotated[
        AwareDatetime | None,
        Field(
            description='Last date/time to book a placement in this installment (ISO 8601). After this point, the seller will not accept new bookings.'
        ),
    ] = None
    cancellation_deadline: Annotated[
        AwareDatetime | None,
        Field(
            description="Last date/time to cancel without penalty (ISO 8601). Cancellations after this point may incur fees per the seller's terms."
        ),
    ] = None
    material_deadlines: Annotated[
        list[material_deadline.MaterialDeadline] | None,
        Field(
            description="Stages for creative material submission. Items MUST be in chronological order by due_at (earliest first). Typical pattern: 'draft' for raw materials the seller will process, 'final' for production-ready assets. Print example: draft artwork then press-ready PDF. Influencer example: talking points then approved script.",
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var booking_deadline : pydantic.types.AwareDatetime | None
var cancellation_deadline : pydantic.types.AwareDatetime | None
var material_deadlines : list[MaterialDeadline] | None
var model_config

Inherited members

class InstallmentDeliveryMetrics (**data: Any)
Expand source code
class InstallmentDeliveryMetrics(DeliveryMetrics):
    installment_ref: installment_ref_1.InstallmentReference
    installment_name: Annotated[
        str | None,
        Field(
            description='Current human-readable installment name. Convenience metadata only; installment_ref is stable identity.'
        ),
    ] = None
    scheduled_at: Annotated[
        AwareDatetime | None,
        Field(
            description="Convenience echo of the installment's scheduled publication or air time."
        ),
    ] = None
    impressions: Any
    spend: Any

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 impressions : Any
var installment_name : str | None
var installment_ref : InstallmentReference
var model_config
var scheduled_at : pydantic.types.AwareDatetime | None
var spend : Any

Inherited members

class InstallmentPropertyDeliveryMetrics (**data: Any)
Expand source code
class InstallmentPropertyDeliveryMetrics(DeliveryMetrics):
    installment_ref: installment_ref_1.InstallmentReference
    installment_name: Annotated[
        str | None,
        Field(description='Current human-readable installment name. Convenience metadata only.'),
    ] = None
    scheduled_at: Annotated[
        AwareDatetime | None,
        Field(
            description="Convenience echo of the installment's scheduled publication or air time."
        ),
    ] = None
    publisher_domain: Annotated[
        str,
        Field(
            description='Publisher or platform authority that namespaces the property identifier, including for an unregistered surface.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    identifier: Annotated[
        identifier_1.Identifier,
        Field(description='Operational identity of the property that delivered the installment.'),
    ]
    property_ref: Annotated[
        property_ref_1.PropertyReference | None,
        Field(
            description="Canonical publisher-scoped catalog identity when available. Its publisher_domain MUST equal the row's publisher_domain."
        ),
    ] = None
    property_name: Annotated[
        str | None,
        Field(description='Current human-readable property name. Convenience metadata only.'),
    ] = None
    impressions: Any
    spend: Any

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 identifier : Identifier
var impressions : Any
var installment_name : str | None
var installment_ref : InstallmentReference
var model_config
var property_name : str | None
var property_ref : PropertyReference | None
var publisher_domain : str
var scheduled_at : pydantic.types.AwareDatetime | None
var spend : Any

Inherited members

class InstallmentReference (**data: Any)
Expand source code
class InstallmentReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    collection_ref: collection_ref_1.CollectionReference
    installment_id: Annotated[
        str, Field(description='Installment ID within the referenced collection.', 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 collection_ref : CollectionReference
var installment_id : str
var model_config

Inherited members

class Intent (*args, **kwds)
Expand source code
class Intent(StrEnum):
    test = 'test'
    speculative = 'speculative'
    planning = 'planning'
    live_rfp = 'live_rfp'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var live_rfp
var planning
var speculative
var test
class IntervalId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class IntervalId(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class InventoryListApplication1 (**data: Any)
Expand source code
class InventoryListApplication1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    list_type: Annotated[
        Literal['property'], Field(description='The receipt describes a property list.')
    ] = 'property'
    effect: Annotated[
        Effect,
        Field(
            description='Whether matching properties were retained as an allowlist or removed as a blocklist.'
        ),
    ]
    agent_url: Annotated[
        AnyUrl, Field(description='Agent URL from the effective property-list targeting reference.')
    ]
    list_id: Annotated[
        str,
        Field(
            description='Identifier from the effective property-list targeting reference.',
            min_length=1,
        ),
    ]
    resolved_at: Annotated[
        AwareDatetime,
        Field(
            description='Timestamp identifying the complete resolved-list snapshot the seller evaluated. If the list response supplied resolved_at, the seller MUST copy it; otherwise the seller records when it completed assembling the snapshot, including all fetched pages.'
        ),
    ]
    evaluated_at: Annotated[
        AwareDatetime,
        Field(
            description="When the seller intersected that snapshot with this product's then-current inventory."
        ),
    ]
    summary: Annotated[
        Summary,
        Field(
            description="Partition of every entry in the resolved list snapshot against this product's common pre-list inventory baseline."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var effect : Effect
var evaluated_at : pydantic.types.AwareDatetime
var list_id : str
var list_type : Literal['adcp.types.domains.core.property']
var model_config
var resolved_at : pydantic.types.AwareDatetime
var summary : Summary

Inherited members

class InventoryListApplication2 (**data: Any)
Expand source code
class InventoryListApplication2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    list_type: Annotated[
        Literal['collection'], Field(description='The receipt describes a collection list.')
    ] = 'collection'
    effect: Annotated[
        Effect,
        Field(
            description='Whether matching collections were retained as an allowlist or removed as a blocklist.'
        ),
    ]
    agent_url: Annotated[
        AnyUrl,
        Field(description='Agent URL from the effective collection-list targeting reference.'),
    ]
    list_id: Annotated[
        str,
        Field(
            description='Identifier from the effective collection-list targeting reference.',
            min_length=1,
        ),
    ]
    resolved_at: Annotated[
        AwareDatetime,
        Field(
            description='Timestamp identifying the complete resolved-list snapshot the seller evaluated. If the list response supplied resolved_at, the seller MUST copy it; otherwise the seller records when it completed assembling the snapshot, including all fetched pages.'
        ),
    ]
    evaluated_at: Annotated[
        AwareDatetime,
        Field(
            description="When the seller intersected that snapshot with this product's then-current inventory."
        ),
    ]
    summary: Annotated[
        Summary2,
        Field(
            description="Partition of every entry in the resolved list snapshot against this product's common pre-list inventory baseline."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var effect : Effect
var evaluated_at : pydantic.types.AwareDatetime
var list_id : str
var list_type : Literal['adcp.types.domains.core.collection']
var model_config
var resolved_at : pydantic.types.AwareDatetime
var summary : Summary2

Inherited members

class Issue (**data: Any)
Expand source code
class Issue(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    pointer: Annotated[
        str,
        Field(
            description="RFC 6901 JSON Pointer to the offending field in the request payload (e.g., '/packages/0/targeting/geo_countries/2'). Format chosen to match Ajv's native validation output (`instancePath`); standardized and unambiguous on keys containing `/` or `~`. NOTE: this differs from the legacy top-level `field` which uses JSONPath-lite (`packages[0].targeting.geo_countries[2]`). When sellers populate `field` from `issues[0].pointer` for backward compatibility (see `field` description), they MUST translate the format — `/packages/0/x` → `packages[0].x`. Future major versions will deprecate `field` in favor of `issues[].pointer`."
        ),
    ]
    message: Annotated[
        str,
        Field(description='Human-readable description of why this specific field was rejected.'),
    ]
    keyword: Annotated[
        str,
        Field(
            description="Schema keyword that rejected the payload, drawn from the JSON Schema vocabulary (e.g., 'required', 'type', 'format', 'enum', 'pattern', 'minimum', 'maxLength'). Matches the keyword names emitted by JSON Schema validators (Ajv, jsonschema, etc.) so agents can pattern-match on rejection class without parsing message text. Implementers SHOULD use the validator's native keyword name; do not invent custom values here."
        ),
    ]
    schemaPath: Annotated[
        str | None,
        Field(
            description="Optional. JSON Schema tree path of the rejecting keyword (e.g. '#/properties/packages/items/oneOf/1'). 3.1+ consumers SHOULD prefer `schema_id`; `schemaPath` is retained for 3.0.x compatibility (renamed to `schema_path` in a future major). See error-handling.mdx for the validator-internals production-emit rules."
        ),
    ] = None
    schema_id: Annotated[
        str | None,
        Field(
            description="Optional. `$id` of the rejecting (sub-)schema (e.g. `/schemas/3.1.0/core/activation-key.json`). MUST resolve to a `$id` published in the spec at the version the seller advertises via `get_adcp_capabilities` — either a deep sub-schema (the typical case) or the response-root `$id` (the bundled-tree fallback for tools served from bundles built before #3868). Sellers MUST NOT emit when the rejection occurred against a private extension, server-only sub-schema, or pre-release element — the public-spec replay rationale only holds when the rejecting element is reachable from the public bundle. Sellers populating `schemaPath` SHOULD also populate `schema_id` when they have it so 3.1+ readers don't get strictly less than 3.0.x readers. See error-handling.mdx for resolution guidance and the bundled-tree caveat."
        ),
    ] = None
    discriminator: Annotated[
        list[DiscriminatorItem] | None,
        Field(
            description="Optional. Const-discriminator property/value pair(s) identifying the variant the validator selected from values present in the payload. Sellers MUST populate only when (a) the rejecting schema is a const-discriminated `oneOf` / `anyOf` and (b) the discriminator property is present in the payload — emission on partial-match inference would fingerprint the seller's validator implementation. MUST omit when zero variants survive. Compound discriminators (e.g. `(type, value_type)`) produce multiple entries ordered by declaration in the rejecting schema's `properties` block. Same private-extensions / version-skew carve-out as `schema_id`. See error-handling.mdx."
        ),
    ] = 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 discriminator : list[DiscriminatorItem] | None
var keyword : str
var message : str
var model_config
var pointer : str
var schemaPath : str | None
var schema_id : str | None

Inherited members

class IssueId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class IssueId(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 255, 'min_length': 1, 'pattern': '^[A-Za-z0-9_.:-]{1,255}$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class IssueState (*args, **kwds)
Expand source code
class IssueState(StrEnum):
    open = 'open'
    acknowledged = 'acknowledged'
    resolved = 'resolved'
    waived = 'waived'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var acknowledged
var open
var resolved
var waived
class Issuer5 (**data: Any)
Expand source code
class Issuer5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['agent'],
        Field(
            description='The issuer is an AdCP agent identified by its canonical HTTPS endpoint.'
        ),
    ] = 'agent'
    brand: brand_ref.BrandReference
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='Canonical HTTPS endpoint of the issuing agent. Evaluators compare it using AdCP URL canonicalization rules.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 agent_url : pydantic.networks.AnyUrl
var brand : BrandReference
var ext : ExtensionObject | None
var model_config
var type : Literal['agent']

Inherited members

class Issuer6 (**data: Any)
Expand source code
class Issuer6(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['origin'],
        Field(
            description='The issuer is identified by a canonical HTTPS origin because no AdCP brand or agent identity applies.'
        ),
    ] = 'origin'
    brand: brand_ref.BrandReference
    origin: Annotated[
        AnyUrl,
        Field(
            description='Canonical HTTPS origin with no path, query, fragment, or userinfo. This identifies the issuer; it does not authorize a fetch.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 brand : BrandReference
var ext : ExtensionObject | None
var model_config
var origin : pydantic.networks.AnyUrl
var type : Literal['origin']

Inherited members

class Issuer8 (**data: Any)
Expand source code
class Issuer8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['agent'],
        Field(
            description='The issuer is an AdCP agent identified by its canonical HTTPS endpoint.'
        ),
    ] = 'agent'
    brand: brand_ref.BrandReference
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='Canonical HTTPS endpoint of the issuing agent. Evaluators compare it using AdCP URL canonicalization rules.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 agent_url : pydantic.networks.AnyUrl
var brand : BrandReference
var ext : ExtensionObject | None
var model_config
var type : Literal['agent']

Inherited members

class Issuer9 (**data: Any)
Expand source code
class Issuer9(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['origin'],
        Field(
            description='The issuer is identified by a canonical HTTPS origin because no AdCP brand or agent identity applies.'
        ),
    ] = 'origin'
    brand: brand_ref.BrandReference
    origin: Annotated[
        AnyUrl,
        Field(
            description='Canonical HTTPS origin with no path, query, fragment, or userinfo. This identifies the issuer; it does not authorize a fetch.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 brand : BrandReference
var ext : ExtensionObject | None
var model_config
var origin : pydantic.networks.AnyUrl
var type : Literal['origin']

Inherited members

class JavascriptAssetRequirements (**data: Any)
Expand source code
class JavascriptAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_file_size_kb: Annotated[
        SchemaInt | None,
        Field(description='Maximum file size in kilobytes for the JavaScript asset', ge=1),
    ] = None
    module_type: Annotated[
        ModuleType | None,
        Field(
            description="Required JavaScript module format. 'script' = classic script, 'module' = ES modules, 'iife' = immediately invoked function expression"
        ),
    ] = None
    strict_mode_required: Annotated[
        StrictBool | None, Field(description='Whether the JavaScript must use strict mode')
    ] = None
    external_resources_allowed: Annotated[
        StrictBool | None,
        Field(description='Whether the JavaScript can load external resources dynamically'),
    ] = None
    allowed_external_domains: Annotated[
        list[str] | None,
        Field(
            description='List of domains the JavaScript may reference for external resources. Only applicable when external_resources_allowed is true.'
        ),
    ] = 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 allowed_external_domains : list[str] | None
var external_resources_allowed : bool | None
var max_file_size_kb : int | None
var model_config
var module_type : ModuleType | None
var strict_mode_required : bool | None

Inherited members

class JavascriptModuleType (*args, **kwds)
Expand source code
class JavascriptModuleType(StrEnum):
    esm = 'esm'
    commonjs = 'commonjs'
    script = 'script'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var commonjs
var esm
var script
class JobItem (**data: Any)
Expand source code
class JobItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    job_id: Annotated[str, Field(description='Unique identifier for this job posting.')]
    title: Annotated[
        str, Field(description="Job title (e.g., 'Senior Software Engineer', 'Marketing Manager').")
    ]
    company_name: Annotated[str, Field(description='Hiring company or organization name.')]
    description: Annotated[
        str,
        Field(description='Full job description including responsibilities and qualifications.'),
    ]
    location: Annotated[
        str | None,
        Field(
            description="Job location as a display string (e.g., 'Amsterdam, NL', 'Remote', 'New York, NY'). Use 'Remote' for fully remote positions."
        ),
    ] = None
    employment_type: Annotated[EmploymentType | None, Field(description='Type of employment.')] = (
        None
    )
    experience_level: Annotated[
        ExperienceLevel | None, Field(description='Required experience level.')
    ] = None
    salary: Annotated[
        Salary | None,
        Field(description='Salary range. Specify min and/or max with currency and period.'),
    ] = None
    date_posted: Annotated[
        date | None, Field(description='Date the job was posted (ISO 8601 date).')
    ] = None
    valid_through: Annotated[
        date | None, Field(description='Application deadline (ISO 8601 date).')
    ] = None
    apply_url: Annotated[AnyUrl | None, Field(description='Direct application URL.')] = None
    job_functions: Annotated[
        list[str] | None,
        Field(
            description="Job function categories (e.g., 'engineering', 'marketing', 'sales', 'finance').",
            min_length=1,
        ),
    ] = None
    industries: Annotated[
        list[str] | None,
        Field(
            description="Industry classifications (e.g., 'technology', 'healthcare', 'retail').",
            min_length=1,
        ),
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering (e.g., 'remote', 'visa-sponsorship', 'equity').",
            min_length=1,
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this job. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (company/role hero), 'images_vertical' (9:16 for Stories), 'logo' (company logo). Enables formats to declare typed image requirements that map unambiguously to the right asset regardless of platform.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 apply_url : pydantic.networks.AnyUrl | None
var assets : list[OfferingAssetGroup] | None
var company_name : str
var date_posted : datetime.date | None
var description : str
var employment_type : EmploymentType | None
var experience_level : ExperienceLevel | None
var ext : ExtensionObject | None
var industries : list[str] | None
var job_functions : list[str] | None
var job_id : str
var location : str | None
var model_config
var salary : Salary | None
var tags : list[str] | None
var title : str
var valid_through : datetime.date | None

Inherited members

class Jurisdiction2 (**data: Any)
Expand source code
class Jurisdiction2(AdCPBaseModel):
    country: Annotated[
        str, Field(description="ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')")
    ]
    region: Annotated[
        str | None,
        Field(description="Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)"),
    ] = None
    regulation: Annotated[
        str,
        Field(
            description="Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')"
        ),
    ]
    label_text: Annotated[
        str | None,
        Field(
            description='Required disclosure label text for this jurisdiction, in the local language'
        ),
    ] = None
    render_guidance: Annotated[
        RenderGuidance | None,
        Field(
            description="How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed."
        ),
    ] = 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 country : str
var label_text : str | None
var model_config
var region : str | None
var regulation : str
var render_guidance : RenderGuidance | None

Inherited members

class Keyword (**data: Any)
Expand source code
class Keyword(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    keyword: Annotated[str, Field(description='The keyword to target', min_length=1)]
    match_type: match_type_1.MatchType | None = match_type_1.MatchType.broad

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 keyword : str
var match_type : MatchType | None
var model_config

Inherited members

class KeywordDeliveryMetrics (**data: Any)
Expand source code
class KeywordDeliveryMetrics(DeliveryMetrics):
    keyword: Annotated[str, Field(description='The targeted keyword')]
    match_type: match_type_1.MatchType
    impressions: Any
    spend: Any

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 impressions : Any
var keyword : str
var match_type : MatchType
var model_config
var spend : Any

Inherited members

class KeywordRequirement (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class KeywordRequirement(RootModel[Required | KeywordRequirement1]):
    root: Required | KeywordRequirement1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[Required, KeywordRequirement1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Required | KeywordRequirement1
class KeywordRequirement1 (**data: Any)
Expand source code
class KeywordRequirement1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    supported_match_types: Annotated[list[match_type.MatchType], Field(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 model_config
var supported_match_types : list[MatchType]

Inherited members

class KeywordSupport (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class KeywordSupport(RootModel[Supported | KeywordSupport1]):
    root: Supported | KeywordSupport1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[Supported, KeywordSupport1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Supported | KeywordSupport1
class KeywordSupport1 (**data: Any)
Expand source code
class KeywordSupport1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    supported_match_types: Annotated[list[match_type.MatchType], Field(min_length=1)]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var model_config
var supported_match_types : list[MatchType]

Inherited members

class LanguageTag (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class LanguageTag(ScalarStr):
    __slots__ = ()
    _constraints = {
        'max_length': 63,
        'min_length': 2,
        'pattern': '^(?:[a-z]{2,8}(?:-[A-Z][a-z]{3})?(?:-(?:[A-Z]{2}|[0-9]{3}))?(?:-(?:[a-z0-9]{5,8}|[0-9][a-z0-9]{3}))*(?:-[0-9a-wy-z](?:-[a-z0-9]{2,8})+)*(?:-x(?:-[a-z0-9]{1,8})+)?|x(?:-[a-z0-9]{1,8})+)$',
    }
    _json_schema_extra = {
        'description': 'A well-formed BCP 47 language tag used by AdCP only as language identity. Script and region may refine that identity; other valid BCP 47 subtags remain part of tag matching but do not make this a general locale-settings object. It does not determine currency, time zone, number/date formatting, market, or legal jurisdiction. The AdCP canonical wire profile requires lower-case language and variants, title-case script, and upper-case region (for example `en-US`, `zh-Hant-TW`, or `x-private`). RFC 5646 comparisons are case-insensitive and its case regularization is optional; AdCP intentionally requires this stricter single wire spelling and receivers MUST reject differently cased tags rather than silently normalizing them. The schema pattern enforces the AdCP casing profile and extension structure for commonly used tags; conforming receivers additionally validate the complete RFC 5646 grammar and registry rules. Every new AdCP field carrying BCP 47 language identity or a concrete language range MUST reference this schema instead of declaring independent string constraints.',
        'examples': ['en-US', 'es-ES', 'zh-Hant-TW', 'x-private'],
        'title': 'Language Tag',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class LatencyPercentiles (**data: Any)
Expand source code
class LatencyPercentiles(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    p50: Annotated[SchemaInt, Field(ge=0)]
    p95: Annotated[SchemaInt, Field(ge=0)]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var p50 : int
var p95 : int

Inherited members

class Layer (*args, **kwds)
Expand source code
class Layer(StrEnum):
    behind_creative = 'behind_creative'
    in_front_of_creative = 'in_front_of_creative'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var behind_creative
var in_front_of_creative
class Level (*args, **kwds)
Expand source code
class Level(StrEnum):
    beginner = 'beginner'
    intermediate = 'intermediate'
    advanced = 'advanced'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var advanced
var beginner
var intermediate
class Limitation (**data: Any)
Expand source code
class Limitation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    reason: Reason
    media_buy_id: ReportingMediaBuyId
    package_ids: Annotated[list[ReportingPackageId] | None, Field(min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var media_buy_id : ReportingMediaBuyId
var model_config
var package_ids : list[ReportingPackageId] | None
var reason : Reason

Inherited members

class LimitedSeries (**data: Any)
Expand source code
class LimitedSeries(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    total_installments: Annotated[
        SchemaInt, Field(description='Planned number of installments in the series', ge=1)
    ]
    starts: Annotated[
        AwareDatetime | None, Field(description='When the series begins (ISO 8601)')
    ] = None
    ends: Annotated[AwareDatetime | None, Field(description='When the series ends (ISO 8601)')] = (
        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 ends : pydantic.types.AwareDatetime | None
var model_config
var starts : pydantic.types.AwareDatetime | None
var total_installments : int

Inherited members

class ListingType (*args, **kwds)
Expand source code
class ListingType(StrEnum):
    for_sale = 'for_sale'
    for_rent = 'for_rent'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var for_rent
var for_sale
class LocalizedCreativeAsset (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class LocalizedCreativeAsset(
    RootModel[
        LocalizedCreativeAsset2
        | LocalizedCreativeAsset3
        | LocalizedCreativeAsset4
        | LocalizedCreativeAsset5
        | LocalizedCreativeAsset7
        | LocalizedCreativeAsset8
        | LocalizedCreativeAsset9
        | LocalizedCreativeAsset10
        | LocalizedCreativeAsset11
        | LocalizedCreativeAsset12
        | LocalizedCreativeAsset13
        | LocalizedCreativeAsset14
        | LocalizedCreativeAsset15
        | LocalizedCreativeAsset16
        | LocalizedCreativeAsset17
        | LocalizedCreativeAsset18
        | LocalizedCreativeAsset19
        | LocalizedCreativeAsset20
        | LocalizedCreativeAsset21
        | LocalizedCreativeAsset22
    ]
):
    root: Annotated[
        LocalizedCreativeAsset2
        | LocalizedCreativeAsset3
        | LocalizedCreativeAsset4
        | LocalizedCreativeAsset5
        | LocalizedCreativeAsset7
        | LocalizedCreativeAsset8
        | LocalizedCreativeAsset9
        | LocalizedCreativeAsset10
        | LocalizedCreativeAsset11
        | LocalizedCreativeAsset12
        | LocalizedCreativeAsset13
        | LocalizedCreativeAsset14
        | LocalizedCreativeAsset15
        | LocalizedCreativeAsset16
        | LocalizedCreativeAsset17
        | LocalizedCreativeAsset18
        | LocalizedCreativeAsset19
        | LocalizedCreativeAsset20
        | LocalizedCreativeAsset21
        | LocalizedCreativeAsset22,
        Field(
            description='An asset inside a materialized creative locale variant. Text and markdown assets may omit language when they make no language claim. When language is present, it MUST use the shared AdCP BCP 47 wire profile; conformance additionally requires exact equality with the enclosing variant locale.',
            title='Localized Creative Asset',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[LocalizedCreativeAsset2, LocalizedCreativeAsset3, LocalizedCreativeAsset4, LocalizedCreativeAsset5, LocalizedCreativeAsset7, LocalizedCreativeAsset8, LocalizedCreativeAsset9, LocalizedCreativeAsset10, LocalizedCreativeAsset11, LocalizedCreativeAsset12, LocalizedCreativeAsset13, LocalizedCreativeAsset14, LocalizedCreativeAsset15, LocalizedCreativeAsset16, LocalizedCreativeAsset17, LocalizedCreativeAsset18, LocalizedCreativeAsset19, LocalizedCreativeAsset20, LocalizedCreativeAsset21, LocalizedCreativeAsset22]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : LocalizedCreativeAsset2 | LocalizedCreativeAsset3 | LocalizedCreativeAsset4 | LocalizedCreativeAsset5 | LocalizedCreativeAsset7 | LocalizedCreativeAsset8 | LocalizedCreativeAsset9 | LocalizedCreativeAsset10 | LocalizedCreativeAsset11 | LocalizedCreativeAsset12 | LocalizedCreativeAsset13 | LocalizedCreativeAsset14 | LocalizedCreativeAsset15 | LocalizedCreativeAsset16 | LocalizedCreativeAsset17 | LocalizedCreativeAsset18 | LocalizedCreativeAsset19 | LocalizedCreativeAsset20 | LocalizedCreativeAsset21 | LocalizedCreativeAsset22
class LocalizedCreativeAsset1 (**data: Any)
Expand source code
class LocalizedCreativeAsset1(AdCPBaseModel):
    pass

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 model_config

Inherited members

class LocalizedCreativeAsset10 (**data: Any)
Expand source code
class LocalizedCreativeAsset10(JavascriptAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset11 (**data: Any)
Expand source code
class LocalizedCreativeAsset11(ZipAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset12 (**data: Any)
Expand source code
class LocalizedCreativeAsset12(WebhookAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset13 (**data: Any)
Expand source code
class LocalizedCreativeAsset13(CssAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset14 (**data: Any)
Expand source code
class LocalizedCreativeAsset14(LocalizedCreativeAsset1):
    pass

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 model_config

Inherited members

class LocalizedCreativeAsset15 (**data: Any)
Expand source code
class LocalizedCreativeAsset15(MarkdownAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset16 (**data: Any)
Expand source code
class LocalizedCreativeAsset16(BriefAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset17 (**data: Any)
Expand source code
class LocalizedCreativeAsset17(CatalogAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset18 (**data: Any)
Expand source code
class LocalizedCreativeAsset18(LocalizedCreativeAsset14):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset19 (**data: Any)
Expand source code
class LocalizedCreativeAsset19(CardAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset2 (**data: Any)
Expand source code
class LocalizedCreativeAsset2(ImageAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset20 (**data: Any)
Expand source code
class LocalizedCreativeAsset20(PixelTrackerAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset21 (**data: Any)
Expand source code
class LocalizedCreativeAsset21(VastTrackerAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset22 (**data: Any)
Expand source code
class LocalizedCreativeAsset22(DaastTrackerAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset3 (**data: Any)
Expand source code
class LocalizedCreativeAsset3(VideoAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset4 (**data: Any)
Expand source code
class LocalizedCreativeAsset4(AudioAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset5 (**data: Any)
Expand source code
class LocalizedCreativeAsset5(LocalizedCreativeAsset14):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset7 (**data: Any)
Expand source code
class LocalizedCreativeAsset7(TextAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset8 (**data: Any)
Expand source code
class LocalizedCreativeAsset8(UrlAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class LocalizedCreativeAsset9 (**data: Any)
Expand source code
class LocalizedCreativeAsset9(HtmlAsset, LocalizedCreativeAsset1):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Location1 (**data: Any)
Expand source code
class Location1(Location8):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Location13 (**data: Any)
Expand source code
class Location13(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    field: Annotated[
        Literal['content'], Field(description='Asset field containing this occurrence.')
    ] = 'content'
    occurrence: Annotated[
        SchemaInt,
        Field(
            description='Zero-based occurrence of this exact token within the named field.', ge=0
        ),
    ]
    context: asset_union.MacroValueContext

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 context : MacroValueContext
var field : Literal['content']
var model_config
var occurrence : int

Inherited members

class Location17 (**data: Any)
Expand source code
class Location17(Location):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Location18 (**data: Any)
Expand source code
class Location18(Location):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Location2 (**data: Any)
Expand source code
class Location2(Location):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Location26 (**data: Any)
Expand source code
class Location26(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    field: Annotated[
        Literal['content'], Field(description='Asset field containing this occurrence.')
    ] = 'content'
    occurrence: Annotated[
        SchemaInt,
        Field(
            description='Zero-based occurrence of this exact token within the named field.', ge=0
        ),
    ]
    context: asset_union.MacroValueContext

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 context : MacroValueContext
var field : Literal['content']
var model_config
var occurrence : int

Inherited members

class Location4 (**data: Any)
Expand source code
class Location4(Location):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Location5 (**data: Any)
Expand source code
class Location5(Location):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Location6 (**data: Any)
Expand source code
class Location6(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    field: Annotated[Literal['url'], Field(description='Asset field containing this occurrence.')] = 'url'
    occurrence: Annotated[
        SchemaInt,
        Field(
            description='Zero-based occurrence of this exact token within the named field.', ge=0
        ),
    ]
    context: MacroValueContext

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 context : MacroValueContext
var field : Literal['url']
var model_config
var occurrence : int

Inherited members

class Location8 (**data: Any)
Expand source code
class Location8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    field: Annotated[
        Literal['content'], Field(description='Asset field containing this occurrence.')
    ] = 'content'
    occurrence: Annotated[
        SchemaInt,
        Field(
            description='Zero-based occurrence of this exact token within the named field.', ge=0
        ),
    ]
    context: MacroValueContext

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 context : MacroValueContext
var field : Literal['content']
var model_config
var occurrence : int

Inherited members

class Location9 (**data: Any)
Expand source code
class Location9(Location6):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Locator (**data: Any)
Expand source code
class Locator(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['credential_uri'] = 'credential_uri'
    credential_uri: Annotated[
        AnyUrl,
        Field(
            description='HTTPS URI of the credential. Before any fetch, evaluators MUST match its canonical origin to credential_origins on the accepted issuer capability and then apply the attestation fetch contract.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 credential_uri : pydantic.networks.AnyUrl
var ext : ExtensionObject | None
var model_config
var type : Literal['credential_uri']

Inherited members

class Locator1 (**data: Any)
Expand source code
class Locator1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['issuer_credential_id'] = 'issuer_credential_id'
    credential_id: Annotated[
        str,
        Field(
            description="Stable credential identifier in the issuer's namespace. It is meaningful only together with issuer and resolver_id.",
            max_length=1024,
            min_length=1,
        ),
    ]
    resolver_id: Annotated[
        str,
        Field(
            description='Identifier of a resolver already published in the matched accepted_issuers[].resolvers[] capability. A presenter cannot supply or override its URL.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9._:-]+$',
        ),
    ]
    ext: ext_1.ExtensionObject | 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 credential_id : str
var ext : ExtensionObject | None
var model_config
var resolver_id : str
var type : Literal['issuer_credential_id']

Inherited members

class ME (*args, **kwds)
Expand source code
class ME(StrEnum):
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var zip
var zip_plus_four
class MacroBearingUrl1 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class MacroBearingUrl1(RootModel[AnyUrl]):
    root: Annotated[
        AnyUrl,
        Field(
            description='Backward-compatible URL value that preserves the existing `uri-template` branch (including deep links, protocol-relative references, and RFC 6570 host variables) while additionally accepting absolute HTTP(S) URLs with byte-preserved macro delimiters not legal in a strict URI, including `%%...%%`, `[...]`, and `${...}`. Macro-bearing HTTP(S) URLs require a valid lexical authority and valid percent triplets; an AdCP verifier replaces each recognized token with an unreserved sentinel and validates the resulting absolute URI. Token semantics are established only by `macro_declarations`.',
            title='Macro-bearing URL',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[AnyUrl]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : pydantic.networks.AnyUrl
class MacroBearingUrl2 (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class MacroBearingUrl2(ScalarStr):
    __slots__ = ()
    _constraints = {
        'pattern': '^https?://(?:[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?|\\[[0-9A-Fa-f:.]+\\])(?::[0-9]{1,5})?(?:[/?#](?:[^%\\s\\u0000-\\u001F\\u007F"<>`\\\\]|%[0-9A-Fa-f]{2}|%%[A-Za-z0-9_.:-]+%%)*)?$',
    }
    _json_schema_extra = {
        'description': 'Backward-compatible URL value that preserves the existing `uri-template` branch (including deep links, protocol-relative references, and RFC 6570 host variables) while additionally accepting absolute HTTP(S) URLs with byte-preserved macro delimiters not legal in a strict URI, including `%%...%%`, `[...]`, and `${...}`. Macro-bearing HTTP(S) URLs require a valid lexical authority and valid percent triplets; an AdCP verifier replaces each recognized token with an unreserved sentinel and validates the resulting absolute URI. Token semantics are established only by `macro_declarations`.',
        'title': 'Macro-bearing URL',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class MacroBearingUrl3 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class MacroBearingUrl3(RootModel[AnyUrl]):
    root: Annotated[
        AnyUrl,
        Field(
            description='Backward-compatible URL value that preserves the existing `uri-template` branch (including deep links, protocol-relative references, and RFC 6570 host variables) while additionally accepting absolute HTTP(S) URLs with byte-preserved macro delimiters not legal in a strict URI, including `%%...%%`, `[...]`, and `${...}`. Macro-bearing HTTP(S) URLs require a valid lexical authority and valid percent triplets; an AdCP verifier replaces each recognized token with an unreserved sentinel and validates the resulting absolute URI. Token semantics are established only by `macro_declarations`.',
            title='Macro-bearing URL',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[AnyUrl]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : pydantic.networks.AnyUrl
class MacroBearingUrl4 (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class MacroBearingUrl4(ScalarStr):
    __slots__ = ()
    _constraints = {
        'pattern': '^https?://(?:[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?|\\[[0-9A-Fa-f:.]+\\])(?::[0-9]{1,5})?(?:[/?#](?:[^%\\s\\u0000-\\u001F\\u007F"<>`\\\\]|%[0-9A-Fa-f]{2}|%%[A-Za-z0-9_.:-]+%%)*)?$',
    }
    _json_schema_extra = {
        'description': 'Backward-compatible URL value that preserves the existing `uri-template` branch (including deep links, protocol-relative references, and RFC 6570 host variables) while additionally accepting absolute HTTP(S) URLs with byte-preserved macro delimiters not legal in a strict URI, including `%%...%%`, `[...]`, and `${...}`. Macro-bearing HTTP(S) URLs require a valid lexical authority and valid percent triplets; an AdCP verifier replaces each recognized token with an unreserved sentinel and validates the resulting absolute URI. Token semantics are established only by `macro_declarations`.',
        'title': 'Macro-bearing URL',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class MacroDeclaration1 (**data: Any)
Expand source code
class MacroDeclaration1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: MacroMappingStatus
    universal_semantic: Annotated[
        UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: MacroProcessingOperation
    performed_by: Annotated[
        MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    location: Location1
    encoding: Annotated[
        MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location1
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration10 (**data: Any)
Expand source code
class MacroDeclaration10(MacroDeclaration8):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class MacroDeclaration12 (**data: Any)
Expand source code
class MacroDeclaration12(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: asset_union.MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: asset_union.MacroMappingStatus
    universal_semantic: Annotated[
        asset_union.UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: asset_union.MacroProcessingOperation
    performed_by: Annotated[
        asset_union.MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        asset_union.MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    location: Location13
    encoding: Annotated[
        asset_union.MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location13
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration15 (**data: Any)
Expand source code
class MacroDeclaration15(MacroDeclaration_1):
    model_config = ConfigDict(
        extra='forbid',
    )
    location: Location17 | None = None
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: asset_union.MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: asset_union.MacroMappingStatus
    universal_semantic: Annotated[
        asset_union.UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: asset_union.MacroProcessingOperation
    performed_by: Annotated[
        asset_union.MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        asset_union.MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    encoding: Annotated[
        asset_union.MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location17 | None
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration16 (**data: Any)
Expand source code
class MacroDeclaration16(MacroDeclaration_1):
    model_config = ConfigDict(
        extra='forbid',
    )
    location: Location18 | None = None
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: asset_union.MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: asset_union.MacroMappingStatus
    universal_semantic: Annotated[
        asset_union.UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: asset_union.MacroProcessingOperation
    performed_by: Annotated[
        asset_union.MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        asset_union.MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    encoding: Annotated[
        asset_union.MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location18 | None
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration2 (**data: Any)
Expand source code
class MacroDeclaration2(MacroDeclarationModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    location: Location | None = None
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: MacroMappingStatus
    universal_semantic: Annotated[
        UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: MacroProcessingOperation
    performed_by: Annotated[
        MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    encoding: Annotated[
        MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location | None
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration20 (**data: Any)
Expand source code
class MacroDeclaration20(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: asset_union.MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: asset_union.MacroMappingStatus
    universal_semantic: Annotated[
        asset_union.UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: asset_union.MacroProcessingOperation
    performed_by: Annotated[
        asset_union.MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        asset_union.MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    location: Location26
    encoding: Annotated[
        asset_union.MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location26
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration3 (**data: Any)
Expand source code
class MacroDeclaration3(MacroDeclarationModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    location: Location4 | None = None
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: MacroMappingStatus
    universal_semantic: Annotated[
        UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: MacroProcessingOperation
    performed_by: Annotated[
        MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    encoding: Annotated[
        MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location4 | None
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration4 (**data: Any)
Expand source code
class MacroDeclaration4(MacroDeclarationModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    location: Location5 | None = None
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: MacroMappingStatus
    universal_semantic: Annotated[
        UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: MacroProcessingOperation
    performed_by: Annotated[
        MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    encoding: Annotated[
        MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location5 | None
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration5 (**data: Any)
Expand source code
class MacroDeclaration5(MacroDeclarationModel):
    location: Location6 | 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 location : Location6 | None
var model_config

Inherited members

class MacroDeclaration6 (**data: Any)
Expand source code
class MacroDeclaration6(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: MacroMappingStatus
    universal_semantic: Annotated[
        UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: MacroProcessingOperation
    performed_by: Annotated[
        MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    location: Location6
    encoding: Annotated[
        MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location6
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration7 (**data: Any)
Expand source code
class MacroDeclaration7(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: MacroMappingStatus
    universal_semantic: Annotated[
        UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: MacroProcessingOperation
    performed_by: Annotated[
        MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    location: Location8
    encoding: Annotated[
        MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location8
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDeclaration8 (**data: Any)
Expand source code
class MacroDeclaration8(MacroDeclarationModel):
    location: Location9 | 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

Subclasses

Class variables

var location : Location9 | None
var model_config

Inherited members

class MacroDeclaration9 (**data: Any)
Expand source code
class MacroDeclaration9(MacroDeclaration8):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class MacroDeclarationModel (**data: Any)
Expand source code
class MacroDeclarationModel(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declaration_id: Annotated[
        str,
        Field(
            description='Identifier unique within the enclosing asset, used to correlate validation results.',
            min_length=1,
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    token: Annotated[
        str,
        Field(
            description='Exact byte-preserved token expression at this occurrence, including delimiters.',
            min_length=1,
        ),
    ]
    dialect: MacroDialect
    dialect_namespace: Annotated[
        AnyUrl | None,
        Field(
            description='Authority-controlled registry or mapping URI. Required for IAB VAST, IAB DAAST, and vendor dialects.'
        ),
    ] = None
    dialect_revision: Annotated[
        str | None,
        Field(
            description='Immutable registry/mapping revision, release, commit, or digest. Required for IAB VAST, IAB DAAST, and vendor dialects.',
            min_length=1,
        ),
    ] = None
    dialect_semantic: Annotated[
        str,
        Field(
            description='Exact semantic identifier in the cited dialect, such as `CACHEBUSTING`, `PLAYERSTATE`, or a documented vendor name. This is not inferred from token spelling.',
            min_length=1,
        ),
    ]
    mapping_status: MacroMappingStatus
    universal_semantic: Annotated[
        UniversalMacro | None,
        Field(
            description='Verified AdCP universal meaning. Present only when mapping_status is `verified_universal`.'
        ),
    ] = None
    operation: MacroProcessingOperation
    performed_by: Annotated[
        MacroResolver | None,
        Field(
            description='Actor authorized to perform the declared translation or value resolution. Omitted for preservation.'
        ),
    ] = None
    translation_target: Annotated[
        MacroTranslationTarget | None,
        Field(
            description='Required only for `translate_to_native`. The output token contract that replaces this declaration after translation.'
        ),
    ] = None
    location: Location2
    encoding: Annotated[
        MacroEncoding,
        Field(
            description='Encoding for the concrete value. Translation/preservation uses `none` at depth zero.'
        ),
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether terminal delivery must fail if the declared operation cannot complete.'
        ),
    ]
    unavailable_behavior: Annotated[
        UnavailableBehavior,
        Field(
            description='Action when the responsible actor has no value. Omission is legal only for a complete URL query-value occurrence; dialect sentinels require a cited dialect rule.'
        ),
    ]

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 declaration_id : str
var dialect : MacroDialect
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var encoding : MacroEncoding
var location : Location2
var mapping_status : MacroMappingStatus
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroResolver | None
var required : bool
var token : str
var translation_target : MacroTranslationTarget | None
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroDialect (*args, **kwds)
Expand source code
class MacroDialect(StrEnum):
    adcp = 'adcp'
    iab_vast = 'iab_vast'
    iab_daast = 'iab_daast'
    vendor = 'vendor'
    unknown = 'unknown'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var adcp
var iab_daast
var iab_vast
var unknown
var vendor
class MacroMappingStatus (*args, **kwds)
Expand source code
class MacroMappingStatus(StrEnum):
    verified_universal = 'verified_universal'
    dialect_defined = 'dialect_defined'
    unresolved = 'unresolved'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var dialect_defined
var unresolved
var verified_universal
class MacroProcessingCapability (**data: Any)
Expand source code
class MacroProcessingCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    dialect: macro_dialect.MacroDialectFamily
    dialect_namespace: AnyUrl | None = None
    dialect_revision: Annotated[str | None, Field(min_length=1)] = None
    dialect_semantic: Annotated[str, Field(min_length=1)]
    mapping_status: MappingStatus
    universal_semantic: universal_macro.UniversalMacro | None = None
    operation: Operation
    performed_by: macro_resolver.MacroProcessingActor
    supported_contexts: Annotated[list[macro_value_context.MacroValueContext], Field(min_length=1)]
    supported_encodings: Annotated[
        list[macro_encoding.MacroEncoding] | None,
        Field(
            description='Exact supported encoding profiles, not a maximum depth. Required for value resolution.',
            min_length=1,
        ),
    ] = None
    translation_target: macro_translation_target.MacroTranslationTarget | 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 dialect : MacroDialectFamily
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var mapping_status : MappingStatus
var model_config
var operation : Operation
var performed_by : MacroProcessingActor
var supported_contexts : list[MacroValueContext]
var supported_encodings : list[MacroEncoding] | None
var translation_target : MacroTranslationTarget | None
var universal_semantic : UniversalMacro | None

Inherited members

class MacroProcessingOperation (*args, **kwds)
Expand source code
class MacroProcessingOperation(StrEnum):
    translate_to_native = 'translate_to_native'
    resolve_value = 'resolve_value'
    preserve = 'preserve'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var preserve
var resolve_value
var translate_to_native
class MacroResolutionResult (**data: Any)
Expand source code
class MacroResolutionResult(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declaration_id: Annotated[str, Field(min_length=1)]
    asset_path: Annotated[
        str, Field(description='JSON Pointer to the asset carrying the declaration.', pattern='^/')
    ]
    token: Annotated[str, Field(min_length=1)]
    dialect: macro_dialect.MacroDialectFamily
    dialect_namespace: AnyUrl | None = None
    dialect_revision: Annotated[str | None, Field(min_length=1)] = None
    dialect_semantic: Annotated[str, Field(min_length=1)]
    mapping_status: macro_mapping_status.MacroMappingStatus
    universal_semantic: universal_macro.UniversalMacro | None = None
    operation: macro_processing_operation.MacroProcessingOperation
    performed_by: macro_resolver.MacroProcessingActor | None = None
    requested_encoding: macro_encoding.MacroEncoding
    required: StrictBool
    unavailable_behavior: UnavailableBehavior
    status: Status
    reason: macro_resolution_reason.MacroResolutionReason
    matched_encodings: Annotated[
        list[macro_encoding.MacroEncoding] | None,
        Field(description='Exact advertised profiles considered for this match, when relevant.'),
    ] = None
    message: Annotated[str | None, Field(min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_path : str
var declaration_id : str
var dialect : MacroDialectFamily
var dialect_namespace : pydantic.networks.AnyUrl | None
var dialect_revision : str | None
var dialect_semantic : str
var mapping_status : MacroMappingStatus
var matched_encodings : list[MacroEncoding] | None
var message : str | None
var model_config
var operation : MacroProcessingOperation
var performed_by : MacroProcessingActor | None
var reason : MacroResolutionReason
var requested_encoding : MacroEncoding
var required : bool
var status : Status
var token : str
var unavailable_behavior : UnavailableBehavior
var universal_semantic : UniversalMacro | None

Inherited members

class MacroResolver (*args, **kwds)
Expand source code
class MacroResolver(StrEnum):
    buyer = 'buyer'
    creative_agent = 'creative_agent'
    seller = 'seller'
    request_executor = 'request_executor'
    source_ad_server = 'source_ad_server'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var buyer
var creative_agent
var request_executor
var seller
var source_ad_server
class MacroValueContext (*args, **kwds)
Expand source code
class MacroValueContext(StrEnum):
    url_query_value = 'url_query_value'
    url_path_segment = 'url_path_segment'
    opaque = 'opaque'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var opaque
var url_path_segment
var url_query_value
class MappingStatus (*args, **kwds)
Expand source code
class MappingStatus(StrEnum):
    verified_universal = 'verified_universal'
    dialect_defined = 'dialect_defined'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var dialect_defined
var verified_universal
class MarkdownAssetRequirements (**data: Any)
Expand source code
class MarkdownAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    max_length: Annotated[SchemaInt | None, Field(description='Maximum character length', 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

Class variables

var max_length : int | None
var model_config

Inherited members

class MarkdownFlavor (*args, **kwds)
Expand source code
class MarkdownFlavor(StrEnum):
    commonmark = 'commonmark'
    gfm = 'gfm'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var commonmark
var gfm
class Market (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class Market(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[A-Z]{2}$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str

Subclasses

class MaterialDeadline (**data: Any)
Expand source code
class MaterialDeadline(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    stage: Annotated[
        str,
        Field(
            description="Submission stage identifier. Use 'draft' for materials that need seller processing and 'final' for production-ready assets. Sellers may define additional stages.",
            examples=['draft', 'final'],
        ),
    ]
    due_at: Annotated[
        AwareDatetime, Field(description='When materials for this stage are due (ISO 8601)')
    ]
    label: Annotated[
        str | None,
        Field(
            description="What the seller needs at this stage (e.g., 'Talking points and brand guidelines', 'Press-ready PDF with bleed')"
        ),
    ] = 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 due_at : pydantic.types.AwareDatetime
var label : str | None
var model_config
var stage : str

Inherited members

class MaterialStage (**data: Any)
Expand source code
class MaterialStage(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    stage: Annotated[
        str,
        Field(
            description="Stage identifier. Standard values: 'draft' (needs seller processing), 'final' (production-ready).",
            examples=['draft', 'final'],
        ),
    ]
    lead_days: Annotated[
        SchemaInt, Field(description='Days before scheduled_at this stage is due', ge=0)
    ]
    label: Annotated[str | None, Field(description='What the seller needs at this stage')] = 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 label : str | None
var lead_days : int
var model_config
var stage : str

Inherited members

class MaterialSubmission (**data: Any)
Expand source code
class MaterialSubmission(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    url: Annotated[
        AnyUrl | None,
        Field(description='HTTPS URL for uploading or submitting physical creative materials'),
    ] = None
    email: Annotated[
        EmailStr | None, Field(description='Email address for creative material submission')
    ] = None
    instructions: Annotated[
        str | None,
        Field(
            description='Human-readable instructions for material submission (file naming conventions, shipping address, etc.)',
            max_length=2000,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 email : pydantic.networks.EmailStr | None
var ext : ExtensionObject | None
var instructions : str | None
var model_config
var url : pydantic.networks.AnyUrl | None

Inherited members

class MaxBidWithCostPer (**data: Any)
Expand source code
class MaxBidWithCostPer(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['max_bid_with_cost_per'] = 'max_bid_with_cost_per'
    cost_per_strengths: Annotated[
        list[CostPerStrength],
        Field(description='cost_per strengths supported when combined with max_bid.', 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 cost_per_strengths : list[CostPerStrength]
var kind : Literal['max_bid_with_cost_per']
var model_config

Inherited members

class MaxBidWithRoas (**data: Any)
Expand source code
class MaxBidWithRoas(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['max_bid_with_roas'] = 'max_bid_with_roas'
    roas_strengths: Annotated[
        list[RoasStrength],
        Field(description='roas strengths supported when combined with max_bid.', 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 kind : Literal['max_bid_with_roas']
var model_config
var roas_strengths : list[RoasStrength]

Inherited members

class McpWebhookPayload (**data: Any)
Expand source code
class McpWebhookPayload(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Sender-generated delivery key stable across RFC 8785 JCS-equivalent retries of the complete authenticated webhook payload. Publishers MUST generate a cryptographically random value (UUID v4 recommended), bind it immutably to the first canonical payload for the advertised delivery retry horizon, and use a fresh key for a changed payload or distinct delivery. Receivers scope the binding to the authenticated sender identity. Same key plus identical payload while active returns retryable 503; after durable acknowledgement it returns 2xx; same key plus a different canonical payload returns non-retryable 409. This is the transport delivery identity, not request idempotency or stable logical notification identity.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str | None,
        Field(
            description='Optional event-layer identifier for one logical notification. Stable across re-emissions of the same logical event and distinct from the per-delivery `idempotency_key`. For terminal task webhooks, the authoritative terminal identity remains the authenticated seller plus the bound task_id; when notification_id is present, different delivery keys carrying the same value are re-emissions and MUST NOT republish terminal effects. For other event families, population and repair identity remain event-shape-dependent (see notification-type.json enumDescriptions): impairment aliases impairment_id, creative and account notifications use transition identifiers, wholesale events alias event.event_id, and capability changes use a revision-event identifier. Point-in-time delivery events (scheduled, final, delayed, adjusted, window_update) omit this field and dedupe by idempotency_key plus their delivery-report identity. Charset is constrained to `[A-Za-z0-9_.:-]`.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    operation_id: Annotated[
        str,
        Field(
            description='Client-generated correlation identifier for the operation that produced this webhook. Buyers supply this value at webhook registration time via `push_notification_config.operation_id`; sellers MUST echo it verbatim in every webhook payload. Sellers MUST NOT derive `operation_id` by parsing `push_notification_config.url` — the URL is opaque to the seller. Receivers MAY dispatch endpoints by URL path or query string, but MUST correlate the operation using this payload field, not URL-derived values. See [Webhooks — Operation IDs and URL templates](/docs/building/by-layer/L3/webhooks#operation-ids-and-url-templates) for the full normative wire contract.'
        ),
    ]
    task_id: Annotated[
        str,
        Field(
            description='Unique identifier for this task. Use this to correlate webhook notifications with the original task submission.'
        ),
    ]
    task_type: Annotated[
        task_type_1.TaskType,
        Field(
            description='Type of AdCP operation that triggered this webhook. Enables webhook handlers to route to appropriate processing logic.'
        ),
    ]
    protocol: Annotated[
        adcp_protocol.AdcpProtocol | None,
        Field(
            description='AdCP protocol this task belongs to. Helps classify the operation type at a high level.'
        ),
    ] = None
    status: Annotated[
        task_status.TaskStatus,
        Field(
            description='Current task status. Webhooks are triggered for status changes after initial submission.'
        ),
    ]
    timestamp: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when this logical webhook delivery was first generated. Every retry under the same idempotency_key MUST repeat this exact body value, along with every other payload member; only transport/signature metadata such as a fresh RFC 9421 nonce or created parameter may change between attempts.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description='Human-readable summary of the current task state. Provides context about what happened and what action may be needed.'
        ),
    ] = None
    context_id: Annotated[
        str | None,
        Field(
            description='Compatibility metadata copied from the originating response when present. This value alone is not continuation authority and MUST NOT be used to resume input-required or auth-required work or to select session state.'
        ),
    ] = None
    token: Annotated[
        str | None,
        Field(
            description='Authentication token echoed verbatim from [`PushNotificationConfig.token`](/schemas/core/push-notification-config.json). Receivers that configured a token MUST compare it to this value to validate request authenticity, and SHOULD use a constant-time equality check to mitigate timing attacks. Absent when no token was configured at registration. Length bounds mirror the config-side field — receivers MAY reject payloads whose token length falls outside the configured range as a defensive check, provided the length check is performed only after the configured token is known to exist for this subscription, and the length comparison is not used as a fast-path to short-circuit the constant-time compare on equal-length inputs. Receivers MUST NOT treat absence as an authenticity failure when no token was configured.',
            max_length=4096,
            min_length=16,
        ),
    ] = None
    result: Annotated[
        async_response_data.AdcpAsyncResponseData | None,
        Field(
            description='Task-specific payload matching the status. For completed/failed, contains the full task response. For working/input-required/submitted, contains status-specific data. This is the data layer that AdCP specs - same structure used in A2A status.message.parts[].data.'
        ),
    ] = 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 context_id : str | None
var idempotency_key : str
var message : str | None
var model_config
var notification_id : str | None
var operation_id : str
var protocol : AdcpProtocol | None
var result : GetProductsResponse | GetProductsRejected | GetProductsWorking | GetProductsInputRequired | GetProductsSubmitted | RequestProposalsResponse1 | RequestProposalsResponse2 | RequestProposalsResponse3 | RequestProposalsResponse4 | RequestProposalsSubmitted | RefineProposalsResponse1 | RefineProposalsResponse2 | RefineProposalsSubmitted | DeclineProposalsResponse1 | DeclineProposalsResponse2 | MediaBuyCommitmentResponse1 | MediaBuyCommitmentResponse2 | MediaBuyCommitmentResponse3 | ControlMediaBuyResponse1 | ControlMediaBuyResponse2 | ControlMediaBuyResponse3 | CompactTaskSubmitted | CompactTaskWorking | CompactTaskInputRequired | GetSignalsResponse | GetSignalsWorking | GetSignalsSubmitted | CreateMediaBuyResponse1 | CreateMediaBuyResponse2 | CreateMediaBuyResponse3 | CreateMediaBuyWorking | CreateMediaBuyInputRequired | CreateMediaBuySubmitted | UpdateMediaBuyResponse1 | UpdateMediaBuyResponse2 | UpdateMediaBuyResponse3 | UpdateMediaBuyWorking | UpdateMediaBuyInputRequired | UpdateMediaBuySubmitted | MediaBuyDeliveryWebhookResult | BuildCreativeResponse1 | BuildCreativeResponse2 | BuildCreativeResponse3 | BuildCreativeResponse4 | BuildCreativeResponse5 | BuildCreativeResponse6 | PreviewCreativeResponse1 | PreviewCreativeResponse2 | PreviewCreativeResponse3 | PreviewCreativeResponse4 | BuildCreativeWorking | BuildCreativeInputRequired | BuildCreativeSubmitted | GetCreativeFeaturesResponse1 | GetCreativeFeaturesResponse2 | GetCreativeFeaturesResponse3 | GetCreativeFeaturesSubmitted | SyncCreativesResponse1 | SyncCreativesResponse2 | SyncCreativesResponse3 | SyncCreativesWorking | SyncCreativesInputRequired | SyncCreativesSubmitted | SyncCatalogsResponse1 | SyncCatalogsResponse2 | SyncCatalogsResponse3 | SyncCatalogsWorking | SyncCatalogsInputRequired | SyncCatalogsSubmitted | None
var status : TaskStatus
var task_id : str
var task_type : TaskType
var timestamp : pydantic.types.AwareDatetime
var token : str | None

Inherited members

class MeasurementPeriod (**data: Any)
Expand source code
class MeasurementPeriod(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    start: Annotated[
        AwareDatetime, Field(description='ISO 8601 start timestamp for measurement period')
    ]
    end: Annotated[
        AwareDatetime, Field(description='ISO 8601 end timestamp for measurement period')
    ]

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 end : pydantic.types.AwareDatetime
var model_config
var start : pydantic.types.AwareDatetime

Inherited members

class MeasurementReadiness (**data: Any)
Expand source code
class MeasurementReadiness(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        assessment_status.AssessmentStatus,
        Field(
            description="Overall measurement readiness level for this product given the buyer's event setup. 'insufficient' means the product cannot optimize effectively with the current setup."
        ),
    ]
    required_event_types: Annotated[
        list[event_type.EventType] | None,
        Field(
            description='Event types this product needs for effective optimization. Buyers should ensure their event sources cover these types.',
            min_length=1,
        ),
    ] = None
    missing_event_types: Annotated[
        list[event_type.EventType] | None,
        Field(
            description='Event types this product requires that the buyer has not configured. Empty or absent when all required types are covered.'
        ),
    ] = None
    issues: Annotated[
        list[diagnostic_issue.DiagnosticIssue] | None,
        Field(
            description='Actionable issues preventing full measurement readiness. Sellers should limit to the top 3-5 most actionable items. Buyer agents should sort by severity rather than relying on array position.'
        ),
    ] = None
    notes: Annotated[
        str | None,
        Field(
            description='Seller explanation of the readiness assessment, recommendations for improvement, or context about what the buyer needs to change.'
        ),
    ] = 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 issues : list[DiagnosticIssue] | None
var missing_event_types : list[EventType] | None
var model_config
var notes : str | None
var required_event_types : list[EventType] | None
var status : AssessmentStatus

Inherited members

class MeasurementTerms (**data: Any)
Expand source code
class MeasurementTerms(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    billing_measurement: Annotated[
        BillingMeasurement | None,
        Field(
            description="Which vendor's value for the billing metric governs invoicing. The billing metric is determined by the pricing_model on the selected pricing_option (e.g., impressions for CPM, completed views for CPCV, commissionable_value for revenue_share)."
        ),
    ] = None
    makegood_policy: Annotated[
        MakegoodPolicy | None,
        Field(
            description='Remedies available when a performance standard or billing measurement variance is breached. Seller declares which remedy types they support. When a breach occurs, the seller proposes a remedy from this menu; the buyer accepts or disputes.'
        ),
    ] = 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 billing_measurement : BillingMeasurement | None
var makegood_policy : MakegoodPolicy | None
var model_config

Inherited members

class MeasurementWindow (**data: Any)
Expand source code
class MeasurementWindow(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    window_id: Annotated[
        str,
        Field(
            description="Identifier for this maturation stage. Standard broadcast values: 'live' (real-time viewers only), 'c3' (live + 3 days time-shifted), 'c7' (live + 7 days time-shifted). Standard values for other channels include 'tentative' (provisional data available quickly), 'final' (post-processing certified data), 'post_ivt' (digital after invalid-traffic filtering), 'post_sivt' (digital after sophisticated-IVT filtering), 'downloads_7d' / 'downloads_30d' (podcast download maturation). Sellers may define custom IDs.",
            examples=['live', 'c3', 'c7', 'tentative', 'final', 'post_ivt', 'downloads_30d'],
            max_length=50,
        ),
    ]
    description: Annotated[
        str | None,
        Field(
            description='Human-readable description of what this window measures',
            examples=[
                'Live broadcast impressions only',
                'Live plus 7 days of time-shifted viewing',
                'Tentative plays before IVT and fraud-check processing',
                'Final plays after IVT and fraud-check processing',
                'Impressions after sophisticated invalid-traffic filtering',
            ],
            max_length=500,
        ),
    ] = None
    duration_days: Annotated[
        SchemaInt,
        Field(
            description='Number of days of accumulation included in this window before processing begins. For broadcast, this is DVR accumulation (0 = live only, 3 = live + 3 days DVR, 7 = live + 7 days DVR). For channels without an accumulation period (DOOH tentative→final, digital IVT filtering), this is 0 — maturation is entirely vendor processing time captured in expected_availability_days.',
            ge=0,
        ),
    ]
    expected_availability_days: Annotated[
        SchemaInt | None,
        Field(
            description="Expected number of days after delivery before this window's data is available from the measurement vendor. Captures accumulation time plus vendor processing time. Examples: broadcast C7 from VideoAmp ~22 days (7-day accumulation + ~15-day processing); DOOH tentative plays same-day; DOOH final (post-IVT/fraud-check) ~1 day; digital post-SIVT ~2–3 days.",
            ge=0,
        ),
    ] = None
    is_guarantee_basis: Annotated[
        StrictBool | None,
        Field(
            description="Whether this window is the basis for delivery guarantees, reconciliation, and invoicing. A product typically has one guarantee basis window (e.g., C7 for most US broadcast, post-IVT final for DOOH). Buyers reconcile against the guarantee basis window's final numbers."
        ),
    ] = 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 description : str | None
var duration_days : int
var expected_availability_days : int | None
var is_guarantee_basis : bool | None
var model_config
var window_id : str

Inherited members

class MediaBuy (**data: Any)
Expand source code
class MediaBuy(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    media_buy_id: Annotated[str, Field(description="Seller's unique identifier for the media buy")]
    name: Annotated[
        str | None,
        Field(
            description='Human-readable name for this media buy, shared by buyer and seller for trafficking UI display and operational communication. Sellers MUST include the persisted name on read surfaces such as get_media_buys when the media buy was created through AdCP with name. Sellers MAY omit name for media buys created outside AdCP or created without name. This display label is not an identifier or financial reference.',
            max_length=255,
            min_length=1,
            pattern='\\S',
        ),
    ] = None
    accepted_proposal_id: Annotated[
        str | None,
        Field(
            description='Current accepted commercial snapshot. Compact-lifecycle buyers pass this ID to refine_proposals after restart or handoff. Updated atomically when an amendment or negotiated cancellation is accepted.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    accepted_proposal_terms_digest: Annotated[
        str | None,
        Field(
            description='Digest of the current accepted proposal commercial_terms, allowing buyers and governance agents to verify the recovered snapshot.',
            pattern='^sha256:[A-Za-z0-9_-]{43}$',
        ),
    ] = None
    account: Annotated[
        account_1.Account | None, Field(description='Account billed for this media buy')
    ] = None
    status: media_buy_status.MediaBuyStatus
    health: Annotated[
        media_buy_health.MediaBuyHealth | None,
        Field(
            description="Aggregate health based on open impairments[]. Orthogonal to status — a paused, pending, or active buy can each be impaired. Defaults to 'ok' when impairments[] is empty."
        ),
    ] = media_buy_health.MediaBuyHealth.ok
    impairments: Annotated[
        list[impairment.Impairment] | None,
        Field(
            description="Open impairments — upstream dependency state changes that affect delivery for at least one package on this buy. Empty when health is 'ok'. Sellers MUST add an entry on next sync/poll response after a referenced resource transitions to an offline state, and MUST remove the entry (flipping health to 'ok' when the array empties) when the resource returns to a serviceable state. Staleness budget: the snapshot MUST reflect the impairment within 5 minutes of impairment.observed_at regardless of buyer poll cadence — sellers cannot rely on rare buyer polls to defer write propagation. See impairment.coherence assertion for the cross-resource invariant."
        ),
    ] = None
    rejection_reason: Annotated[
        str | None,
        Field(
            description="Reason provided by the seller when status is 'rejected'. Present only when status is 'rejected'."
        ),
    ] = None
    confirmed_at: Annotated[
        AwareDatetime | None,
        Field(
            description='ISO 8601 timestamp when the seller committed to this media buy. May be null until seller commitment occurs in deferred/manual approval flows. Once populated, remains stable through later pause, resume, activation, completion, cancellation, and reporting transitions.'
        ),
    ]
    cancellation: Annotated[
        Cancellation | None,
        Field(description="Cancellation metadata. Present only when status is 'canceled'."),
    ] = None
    total_budget: Annotated[
        StrictFloat, Field(description='Hard aggregate lifetime budget amount', ge=0.0)
    ]
    daily_budget_cap: Annotated[
        StrictFloat | None,
        Field(
            description='Current hard aggregate spend ceiling per calendar day. Sellers MUST echo this whenever an aggregate daily cap is set. It bounds total media-buy spend without allocating or reserving spend for packages.',
            ge=0.0,
        ),
    ] = None
    frequency_cap: Annotated[
        media_buy_frequency_cap.MediaBuyFrequencyCap | None,
        Field(
            description='Current hard MediaBuy-level cap. Sellers MUST echo it whenever set. Its counter aggregates exposures across all participating packages; each package targeting_overlay.frequency_cap remains independently binding.'
        ),
    ] = None
    budget_cap_timezone: Annotated[
        str | None,
        Field(
            description='IANA timezone defining the shared calendar-day boundary for every aggregate and package daily cap on this media buy. Sellers MUST echo it whenever any daily cap is set.'
        ),
    ] = None
    currency: Annotated[
        str | None,
        Field(
            description="Single ISO 4217 denomination for total_budget, every package budget/minimum, and every canonical BiddingPolicy monetary field. Every package's selected pricing option MUST declare this currency; packages requiring another currency belong in a separate media buy.",
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    budget_allocation: Annotated[
        budget_allocation_1.BudgetAllocation | None,
        Field(
            description='Accepted cross-package budget allocation configuration. Omitted means fixed allocation for legacy buys.'
        ),
    ] = None
    pacing: Annotated[
        pacing_1.Pacing | None,
        Field(
            description='Aggregate pacing strategy for total_budget across the media-buy flight.'
        ),
    ] = None
    bidding: Annotated[
        bidding_policy.BiddingPolicy | None,
        Field(
            description='Media-buy-authored bidding policy. This is the complete default inherited by packages that omit package.bidding; `{automatic:true}` is an explicit authored automatic policy. In seller-optimized mode, cost_per/roas bind to the primary budget_allocation optimization goal. In fixed mode, inherited cost_per requires compatible package primary-goal result units and inherited roas requires value-bearing primary goals. Monetary fields use media_buy.currency; every affected pricing option MUST declare the same currency. Package overrides are permitted only where advertised; conflicts MUST be rejected atomically with BIDDING_PLACEMENT_CONFLICT.'
        ),
    ] = None
    packages: Annotated[
        list[package.Package], Field(description='Array of packages within this media buy')
    ]
    context: Annotated[
        context_1.ContextObject | None,
        Field(
            description='Opaque media-buy-level correlation data echoed unchanged from the create_media_buy request. Sellers MUST include persisted context on read surfaces such as get_media_buys when the media buy was created through AdCP with context, so buyers can reconcile seller-assigned media_buy_id values with their own tracking state. Sellers MAY omit context for media buys created outside AdCP or created without context. Sellers MUST NOT parse this object for business logic.'
        ),
    ] = None
    invoice_recipient: Annotated[
        business_entity.BusinessEntity | None,
        Field(
            description="Per-buy override for who receives the invoice. When provided, the seller invoices this entity instead of the account's default billing_entity. The seller MUST validate the invoice recipient is authorized for this account. When governance_agents are configured, the seller MUST include invoice_recipient in the check_governance request."
        ),
    ] = None
    creative_deadline: Annotated[
        AwareDatetime | None, Field(description='ISO 8601 timestamp for creative upload deadline')
    ] = None
    revision: Annotated[
        SchemaInt,
        Field(
            description='Monotonically increasing optimistic concurrency token. Incremented on every mutating state change or update; reads, validation-only calls, and exact idempotency replays do not increment it. Callers SHOULD include this in update_media_buy requests intended to change state — when provided, sellers MUST reject with CONFLICT if the revision does not match the current value, and MUST enforce that comparison atomically with the write.',
            ge=1,
        ),
    ]
    created_at: Annotated[AwareDatetime | None, Field(description='Creation timestamp')] = None
    updated_at: Annotated[AwareDatetime | None, Field(description='Last update timestamp')] = None
    ext: ext_1.ExtensionObject | 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 accepted_proposal_id : str | None
var accepted_proposal_terms_digest : str | None
var account : Account | None
var bidding : BiddingPolicy | None
var budget_allocation : BudgetAllocation1 | BudgetAllocation2 | None
var budget_cap_timezone : str | None
var cancellation : Cancellation | None
var confirmed_at : pydantic.types.AwareDatetime | None
var context : ContextObject | None
var created_at : pydantic.types.AwareDatetime | None
var creative_deadline : pydantic.types.AwareDatetime | None
var currency : str | None
var daily_budget_cap : float | None
var ext : ExtensionObject | None
var frequency_cap : MediaBuyFrequencyCap | None
var health : MediaBuyHealth | None
var impairments : list[Impairment] | None
var invoice_recipient : BusinessEntity | None
var media_buy_id : str
var model_config
var name : str | None
var pacing : Pacing | None
var packages : list[Package]
var rejection_reason : str | None
var revision : int
var status : MediaBuyStatus
var total_budget : float
var updated_at : pydantic.types.AwareDatetime | None

Inherited members

class MediaBuyAvailableAction (**data: Any)
Expand source code
class MediaBuyAvailableAction(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    action: Annotated[
        media_buy_available_action_id.MediaBuyAvailableActionId,
        Field(description='The action identifier.'),
    ]
    mode: Annotated[
        media_buy_action_mode.MediaBuyActionMode,
        Field(
            description='The single mode that applies right now on this buy for this action. Singular because the buy has a concrete state, exactly one mode applies. Buyer SDKs branch on this to decide whether to expect a synchronous response, conditional handling, or an asynchronous approval callback.'
        ),
    ]
    task: Annotated[
        Task | None,
        Field(
            description='Compact-lifecycle task for this resolved action: operational control, commercial refinement, or creative lifecycle mutation.'
        ),
    ] = None
    sla: Annotated[
        sla_window.SlaWindow | None,
        Field(
            description='Optional SLA commitment for this action on this buy. Absence means no commitment, not zero commitment.'
        ),
    ] = None
    change_term_id: media_buy_change_term_id.MediaBuyChangeTermId | None = None
    terms_ref: media_buy_legacy_terms_ref.MediaBuyTermsReference | None = None
    applicable_package_ids: Annotated[
        list[applicable_package_id.ApplicablePackageId] | None,
        Field(
            description='For a package-scoped action, the exact packages currently eligible. Omission means every relevant package. Root actions omit this field.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var action : MediaBuyValidAction | Literal['update_media_buy_frequency_cap']
var applicable_package_ids : list[ApplicablePackageId] | None
var change_term_id : MediaBuyChangeTermId | None
var mode : MediaBuyActionMode
var model_config
var sla : SlaWindow | None
var task : Task | None
var terms_ref : MediaBuyTermsReference | None

Inherited members

class MediaBuyChangeTermId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class MediaBuyChangeTermId(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[A-Za-z0-9_.:-]+$'}
    _json_schema_extra = {
        'description': 'The accepted proposal change_terms[].term_id from which this current-state action projection was derived.',
        'title': 'Media Buy Change Term ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class MediaBuyFeatures (**data: Any)
Expand source code
class MediaBuyFeatures(AdCPBaseModel):
    __pydantic_extra__: Dict[str, StrictBool]
    model_config = ConfigDict(
        extra='allow',
    )
    inline_creative_management: Annotated[
        StrictBool | None,
        Field(
            deprecated=True,
            description='Deprecated 3.x compatibility capability for creatives provided inline in create_media_buy and update_media_buy package payloads. buy_products, accept_proposal, and control_media_buy never accept inline creatives. New integrations use the dedicated creative lifecycle. Removed in 4.0.',
        ),
    ] = None
    property_list_filtering: Annotated[
        StrictBool | None,
        Field(
            description='Honors property_list parameter in get_products to filter results to buyer-approved properties'
        ),
    ] = None
    catalog_management: Annotated[
        StrictBool | None,
        Field(
            description='Supports sync_catalogs task for catalog feed management with platform review and approval'
        ),
    ] = None
    catalog_item_availability_updates: Annotated[
        StrictBool | None,
        Field(
            description='Supports buyer-pushed item_availability_updates and item_availability_queries on sync_catalogs for immediate suppression/restoration and current-state readback in buyer-managed catalogs. Seller declarations may be true only with catalog_management: true; buyer required_features filters may request this feature alone. Requests containing availability operations are synchronous and accept at most 1,000 combined update and query entries. A successful suppress covers selection, dynamic rendering, and cached or pre-generated creatives materialized from the item. Internal lineage MUST retain resolved_account_id, catalog_id, catalog_generation, and item_id. Static creatives supplied or promoted by the buyer without catalog lineage remain outside this automatic guarantee. Suppression persists across feed refreshes and ordinary upserts until restore, expires_at, or catalog deletion. A seller that does not declare true MUST reject availability operations with UNSUPPORTED_FEATURE before lookup or mutation and MUST NOT interpret them as discovery. This does not control seller-owned wholesale inventory or let restore bypass seller controls.'
        ),
    ] = None
    committed_metrics_supported: Annotated[
        StrictBool | None,
        Field(
            description="Seller has per-package snapshot infrastructure for the reporting contract. When true, the seller MUST populate `package.committed_metrics` on committed `create_media_buy` responses where `confirmed_at` is non-null, MUST omit `package.committed_metrics` while `confirmed_at` is null for a provisional buy, and MUST honor append-only mid-flight metric additions via `update_media_buy`. The unified `committed_metrics` array (per the metric-accountability design) covers both standard and vendor-defined metric entries, so a single flag is load-bearing. Buyers filtering on this flag are detecting 'this seller can stamp the reporting contract,' which closes the audit gap from PR #3510 where absence of `committed_metrics` was indistinguishable between 'didn't snapshot' and 'snapshot infrastructure not implemented.'"
        ),
    ] = None
    seller_optimized_budget: Annotated[
        StrictBool | None,
        Field(
            description="Supports the core seller-optimized shared-budget contract for budget_allocation.mode `seller_optimized`: one hard shared total_budget, seller allocation of that total across the buy's packages against budget_allocation.optimization_goals, media-buy-level pacing, and echo of the allocation configuration on buy read surfaces. Sellers declaring true MUST accept eligible explicit-package and proposal executions that use only these core controls and MUST enforce the aggregate budget. Core media-buy pacing: sellers declaring true MUST accept omitted media-buy pacing (which defaults to even when total_budget is present) and pacing `even` on seller-optimized buys; they MAY reject `asap` or `front_loaded` with `UNSUPPORTED_FEATURE` (error.field `pacing`) before any provider mutation, and MUST NOT silently coerce them to `even`. Package-level controls inside a seller-optimized buy are separate capabilities: package budget caps (seller_optimized_package_budgets), package minimum-spend targets (seller_optimized_min_spend_targets), and package pacing (seller_optimized_package_pacing). A seller declaring this feature but not one of those sub-capabilities MUST reject any request that would leave that package control on a seller-optimized buy with `UNSUPPORTED_FEATURE` before any over-subscription validation or provider mutation, and MUST NOT silently drop, soften, or coerce it. Over-subscription validation (`INVALID_REQUEST`) applies only to package controls the seller has declared; see seller_optimized_min_spend_targets. Product combinations may still be rejected when their currencies, optimization capabilities, pricing terms, or delivery constraints are incompatible. Sellers that do not declare this feature MUST reject any request carrying `budget_allocation.mode: 'seller_optimized'` with `UNSUPPORTED_FEATURE` before any provider mutation, and MUST NOT coerce the request to fixed allocation."
        ),
    ] = None
    seller_optimized_package_budgets: Annotated[
        StrictBool | None,
        Field(
            description='Honors package `budget` as an optional hard lifetime package spend cap inside a seller-optimized buy: packages[].budget and new_packages[].budget on create_media_buy and update_media_buy, purchases[].budget on buy_products, package budget controls on control_media_buy, and max_spend_percentage on seller-optimized proposal allocations. The cap is a ceiling, not a reserved or current allocation, and package caps may sum above total_budget. Meaningful only with seller_optimized_budget: true; seller declarations may be true only with seller_optimized_budget: true, while buyer required_features filters may request this feature alone. A seller that declares seller_optimized_budget without this feature MUST reject a request that would leave a package budget on a seller-optimized buy, including an allocation-mode switch that retains fixed-mode package budgets (the buyer clears them with null in the same atomic update), with `UNSUPPORTED_FEATURE` before any over-subscription validation or provider mutation, and MUST NOT issue seller-optimized proposals carrying max_spend_percentage. Does not govern fixed allocation, where package budgets remain required.'
        ),
    ] = None
    seller_optimized_min_spend_targets: Annotated[
        StrictBool | None,
        Field(
            description='Honors package `min_spend_target` as a soft lifetime minimum-spend target inside a seller-optimized buy: packages[].min_spend_target and new_packages[].min_spend_target on create_media_buy and update_media_buy, purchases[].min_spend_target on buy_products, package min_spend_target controls on control_media_buy, and min_spend_target_percentage on seller-optimized proposal allocations. The seller SHOULD attempt to deliver at least the target before allocating incremental spend elsewhere; it is not a billing or delivery guarantee. Meaningful only with seller_optimized_budget: true; seller declarations may be true only with seller_optimized_budget: true, while buyer required_features filters may request this feature alone. Sellers declaring this feature MUST reject package minimum-spend targets summing above total_budget with `INVALID_REQUEST` before mutation, and, when they also declare seller_optimized_package_budgets, MUST likewise reject a min_spend_target above its own package budget. A seller that declares seller_optimized_budget without this feature MUST reject a request carrying a numeric min_spend_target with `UNSUPPORTED_FEATURE` before any over-subscription validation or provider mutation, so an over-subscribed target sent to such a seller yields `UNSUPPORTED_FEATURE`, and MUST NOT issue seller-optimized proposals carrying min_spend_target_percentage.'
        ),
    ] = None
    seller_optimized_package_pacing: Annotated[
        StrictBool | None,
        Field(
            description='Honors package `pacing` as subordinate per-package pacing inside a seller-optimized buy, in addition to the media-buy-level pacing covered by seller_optimized_budget: packages[].pacing and new_packages[].pacing on create_media_buy and update_media_buy, purchases[].pacing on buy_products, package pacing controls on control_media_buy, and allocation pacing on seller-optimized proposals. Package pacing MUST NOT cause delivery to exceed aggregate media-buy pacing. Meaningful only with seller_optimized_budget: true; seller declarations may be true only with seller_optimized_budget: true, while buyer required_features filters may request this feature alone. Package pacing equal to the effective media-buy pacing adds no subordinate constraint and does not require this feature; buyers SHOULD omit package pacing on seller-optimized buys unless this feature is advertised. A seller that declares seller_optimized_budget without this feature MUST reject a request that would leave package pacing differing from media-buy pacing on a seller-optimized buy, including an allocation-mode switch that retains such fixed-mode package pacing (the buyer can align it in the same update), with `UNSUPPORTED_FEATURE` before any provider mutation, and MUST NOT issue seller-optimized proposals carrying allocation pacing. Does not govern package pacing in fixed allocation.'
        ),
    ] = None
    bidding_policy: Annotated[
        bidding_policy_capability.BiddingPolicyCapability | None,
        Field(
            description='Structured support for canonical bidding by authored scope, allocation context, mode, strength, and strength-qualified multi-field combination. Presence does not imply support for both scopes, both allocation modes, or every policy shape. Sellers MUST preserve every advertised semantic exactly and reject unadvertised policies rather than translating them.'
        ),
    ] = 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 bidding_policy : BiddingPolicyCapability | None
var canonical_creatives : bool | None
var catalog_item_availability_updates : bool | None
var catalog_management : bool | None
var committed_metrics_supported : bool | None
var model_config
var property_list_filtering : bool | None
var seller_optimized_budget : bool | None
var seller_optimized_min_spend_targets : bool | None
var seller_optimized_package_budgets : bool | None
var seller_optimized_package_pacing : bool | None

Instance variables

var inline_creative_management : bool | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.

Inherited members

class MediaBuyFrequencyCap (**data: Any)
Expand source code
class MediaBuyFrequencyCap(FrequencyCap):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class MediaBuyFrequencyCapCapability (**data: Any)
Expand source code
class MediaBuyFrequencyCapCapability(FrequencyCapConstraints):
    supported_control_modes: Annotated[
        list[media_buy_frequency_cap_control_mode.MediaBuyFrequencyCapControlMode],
        Field(
            description='FrequencyCap shapes accepted by the product. max_impressions_and_suppress means both controls may appear together and are enforced with AND semantics.',
            min_length=1,
        ),
    ]
    supported_per_units: Any
    max_impressions_constraints: Any
    window_constraints: Any

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 max_impressions_constraints : Any
var model_config
var supported_control_modes : list[MediaBuyFrequencyCapControlMode]
var supported_per_units : Any
var window_constraints : Any

Inherited members

class MediaBuyFrequencyCapRequirement (**data: Any)
Expand source code
class MediaBuyFrequencyCapRequirement(FrequencyCapRequirements):
    supported_control_modes: Annotated[
        list[media_buy_frequency_cap_control_mode.MediaBuyFrequencyCapControlMode] | None,
        Field(min_length=1),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var supported_control_modes : list[MediaBuyFrequencyCapControlMode] | None

Inherited members

class MediaBuyFrequencyCapSupport (**data: Any)
Expand source code
class MediaBuyFrequencyCapSupport(FrequencyCapConstraints):
    supported_control_modes: Annotated[
        list[media_buy_frequency_cap_control_mode.MediaBuyFrequencyCapControlMode] | None,
        Field(
            description='FrequencyCap shapes accepted by the product. max_impressions_and_suppress means both controls may appear together and are enforced with AND semantics.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var supported_control_modes : list[MediaBuyFrequencyCapControlMode] | None

Inherited members

class MediaBuyTermsReference (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class MediaBuyTermsReference(ScalarStr):
    __slots__ = ()
    _json_schema_extra = {
        'description': 'Deprecated 3.1 opaque commercial-terms pointer. A 3.2 compatibility projection MAY echo change_term_id here for older buyers, but new buyers MUST prefer change_term_id and MUST NOT assume an arbitrary 3.1 value identifies an accepted change term.',
        'title': 'Media Buy Terms Reference',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class Metric7 (**data: Any)
Expand source code
class Metric7(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Annotated[
        Literal['vendor'],
        Field(description='Vendor-defined metric, identified by the tuple `(vendor, metric_id)`.'),
    ] = 'vendor'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description="Vendor that defines and computes this metric. Same identity discipline as `vendor_metric_value.vendor` and `committed_metrics` vendor-scope entries. Distinct from the row-level `vendor` field at the top of `performance-feedback`, which identifies the *source* of the feedback (the party producing it); this nested vendor identifies the *vendor that defines the metric* (which may or may not be the same party). Typically the same when third-party verification reports its own metric; can differ when a buyer's MMM tool reports on a separately-defined vendor metric."
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(description="Identifier for the metric within the vendor's vocabulary."),
    ]
    qualifier: Annotated[
        Qualifier | None,
        Field(
            description='Optional disambiguator mirroring the vendor-scope qualifier on `committed_metrics` — same closed key set as standard-scope entries.'
        ),
    ] = 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 metric_id : VendorMetricId
var model_config
var qualifier : Qualifier | None
var scope : Literal['vendor']
var vendor : BrandReference

Inherited members

class MetricOptimization (**data: Any)
Expand source code
class MetricOptimization(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    supported_metrics: Annotated[
        list[SupportedMetric],
        Field(
            description='Metric kinds this product can optimize for. Buyers should only request metric goals for kinds listed here. **DEPRECATED values** (slated for removal at next major): `attention_seconds` and `attention_score` — declare vendor-attested attention/quality metrics via `vendor_metric_optimization.supported_metrics[]` with an explicit vendor binding instead. Sellers MAY reject the deprecated values with `TERMS_REJECTED` and a suggestion to use the `vendor_metric` kind.',
            min_length=1,
        ),
    ]
    supported_reach_units: Annotated[
        list[reach_unit.ReachUnit] | None,
        Field(
            description="Reach units this product can optimize for. Required when supported_metrics includes 'reach'. Buyers must set reach_unit to a value in this list on reach optimization goals — sellers reject unsupported values.",
            min_length=1,
        ),
    ] = None
    supported_view_durations: Annotated[
        list[SupportedViewDuration] | None,
        Field(
            description="Video view duration thresholds (in seconds) this product supports for completed_views goals. Only relevant when supported_metrics includes 'completed_views'. When absent, the seller uses their platform default. Buyers must set view_duration_seconds to a value in this list — sellers reject unsupported values."
        ),
    ] = None
    supported_viewability_standards: Annotated[
        list[viewability_standard.ViewabilityStandard] | None,
        Field(
            description="Viewability standards this product can optimize viewable_rate goals against. Only relevant when supported_metrics includes 'viewable_rate'. When absent, buyers cannot assume a specific standard is supported and sellers reject unsupported values. Buyers must set the goal's standard to a value in this list when it is present.",
            min_length=1,
        ),
    ] = None
    supported_targets: Annotated[
        list[SupportedTarget] | None,
        Field(
            description='Target kinds available for metric goals on this product. Values match target.kind on the optimization goal. Only these target kinds are accepted — goals with unlisted target kinds will be rejected. When omitted, buyers can set target-less metric goals (maximize volume within budget) but cannot set specific targets.'
        ),
    ] = 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 model_config
var supported_metrics : list[SupportedMetric]
var supported_reach_units : list[ReachUnit] | None
var supported_targets : list[SupportedTarget] | None
var supported_view_durations : list[SupportedViewDuration] | None
var supported_viewability_standards : list[ViewabilityStandard] | None

Inherited members

class MetroRequirement (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class MetroRequirement(RootModel[Required | MetroRequirement1]):
    root: Required | MetroRequirement1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[Required, MetroRequirement1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Required | MetroRequirement1
class MetroRequirement1 (**data: Any)
Expand source code
class MetroRequirement1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    systems: Annotated[list[metro_system.MetroAreaSystem], Field(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 model_config
var systems : list[MetroAreaSystem]

Inherited members

class MetroSupport (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class MetroSupport(RootModel[Supported | MetroSupport1]):
    root: Supported | MetroSupport1
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[Supported, MetroSupport1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Supported | MetroSupport1
class MetroSupport1 (**data: Any)
Expand source code
class MetroSupport1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    systems: Annotated[list[metro_system.MetroAreaSystem], Field(min_length=1)]
    max_values_per_package: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_packages: Annotated[
        SchemaInt | None,
        Field(
            description='Optional maximum number of independently targeted packages the seller will create from this configured product.',
            ge=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var max_packages : int | None
var max_values_per_package : int | None
var model_config
var systems : list[MetroAreaSystem]

Inherited members

class Mileage (**data: Any)
Expand source code
class Mileage(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    value: Annotated[StrictFloat, Field(description='Mileage value.', ge=0.0)]
    unit: Annotated[Unit, Field(description='Distance unit.')]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var unit : Unit
var value : float

Inherited members

class MimeType (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class MimeType(ScalarStr):
    __slots__ = ()
    _constraints = {
        'pattern': '^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*$',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class MismatchCode (*args, **kwds)
Expand source code
class MismatchCode(StrEnum):
    scope_media_buy_missing = 'scope_media_buy_missing'
    coverage_short = 'coverage_short'
    metric_missing = 'metric_missing'
    schema_nonconformant = 'schema_nonconformant'
    currency_mismatch = 'currency_mismatch'
    period_mismatch = 'period_mismatch'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var coverage_short
var currency_mismatch
var metric_missing
var period_mismatch
var schema_nonconformant
var scope_media_buy_missing
class MissingMetric1 (**data: Any)
Expand source code
class MissingMetric1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['standard'] = 'standard'
    metric_id: available_metric.AvailableMetric
    qualifier: Annotated[
        Qualifier | None,
        Field(
            description='Mirrors the qualifier on `committed_metrics` so the missing entry preserves the contract distinction (e.g., flagging MRC viewability as missing when only GroupM was reported, vendor-attested completion as missing when only seller-attested was reported, or deterministic_purchase attribution as missing when only probabilistic was reported). MUST match the qualifier on the corresponding `committed_metrics` entry the missing flag refers to.'
        ),
    ] = 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 metric_id : AvailableMetric
var model_config
var qualifier : Qualifier | None
var scope : Literal['standard']

Inherited members

class MissingMetric2 (**data: Any)
Expand source code
class MissingMetric2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['vendor'] = 'vendor'
    vendor: brand_ref.BrandReference
    metric_id: vendor_metric_id.VendorMetricId
    qualifier: Annotated[
        Qualifier | None,
        Field(
            description='Mirrors the qualifier on the corresponding vendor-scope `committed_metrics` entry. MUST match that entry so reconciliation joins on (vendor, metric_id, qualifier).'
        ),
    ] = 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 metric_id : VendorMetricId
var model_config
var qualifier : Qualifier | None
var scope : Literal['vendor']
var vendor : BrandReference

Inherited members

class Modality (*args, **kwds)
Expand source code
class Modality(StrEnum):
    online = 'online'
    in_person = 'in_person'
    hybrid = 'hybrid'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var hybrid
var in_person
var online
class ModuleType (*args, **kwds)
Expand source code
class ModuleType(StrEnum):
    script = 'script'
    module = 'module'
    iife = 'iife'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var iife
var module
var script
class MoovAtomPosition (*args, **kwds)
Expand source code
class MoovAtomPosition(StrEnum):
    start = 'start'
    end = 'end'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var end
var start
class Multiplicity (**data: Any)
Expand source code
class Multiplicity(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    supports_catalog_fanout: Annotated[
        StrictBool | None, Field(description='Whether this transformer accepts max_creatives.')
    ] = False
    max_creatives_limit: Annotated[
        SchemaInt | None,
        Field(description='Per-transformer ceiling on max_creatives (≤ the agent ceiling).', ge=1),
    ] = None
    supports_variants: Annotated[
        StrictBool | None,
        Field(description='Whether this transformer accepts max_variants > 1 / variant_axis.'),
    ] = False
    max_variants_limit: Annotated[
        SchemaInt | None,
        Field(description='Per-transformer ceiling on max_variants (≤ the agent ceiling).', ge=1),
    ] = None
    variant_dimensions: Annotated[
        list[VariantDimension] | None,
        Field(description="Variant axis dimensions this transformer supports (⊆ the agent's)."),
    ] = 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 max_creatives_limit : int | None
var max_variants_limit : int | None
var model_config
var supports_catalog_fanout : bool | None
var supports_variants : bool | None
var variant_dimensions : list[VariantDimension] | None

Inherited members

class NativeCommitEvidence (**data: Any)
Expand source code
class NativeCommitEvidence(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    native_version_ref: reporting_native_version_ref.ReportingNativeVersionReference
    observed_through: ObservedThrough

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var native_version_ref : ReportingNativeVersionReference
var observed_through : ObservedThrough

Inherited members

class NegativeKeyword (**data: Any)
Expand source code
class NegativeKeyword(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    keyword: Annotated[str, Field(description='The keyword to exclude', min_length=1)]
    match_type: match_type_1.MatchType

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 keyword : str
var match_type : MatchType
var model_config

Inherited members

class NonblockingImpact (**data: Any)
Expand source code
class NonblockingImpact(Impact):
    effect: Effect1 | 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 effect : Effect1 | None
var model_config

Inherited members

class NonblockingImpacts (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class NonblockingImpacts(RootModel[list[NonblockingImpact]]):
    root: Annotated[
        list[NonblockingImpact],
        Field(
            description='Account areas the seller evaluated for continuity or reauthorization. Non-blocked outcomes cannot carry a blocked effect.',
            max_length=16,
            min_length=1,
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[list[NonblockingImpact]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[NonblockingImpact]
class NotificationConfig (**data: Any)
Expand source code
class NotificationConfig(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    subscriber_id: Annotated[
        str,
        Field(
            description="Buyer-supplied identifier for this subscription endpoint. This is the stable logical key within one account's notification_configs[] set: re-sending the same subscriber_id for the same account replaces that subscriber's URL, event_types, authentication selector, and active flag rather than creating a duplicate. Echoed on every webhook payload and on every `webhook_activity[]` record fired against this config so the buyer can attribute fires across multiple endpoints. MUST be unique within the account's `notification_configs[]`. Sending two entries with the same `subscriber_id` in a single `sync_accounts` request array is rejected as a per-account validation failure with `INVALID_REQUEST` or `VALIDATION_ERROR`, and `error.field` MUST point at the duplicate entry. `subscriber_id` is the stable match key for the per-account declarative-replace diff. Always required (even with a single subscriber) so the SDK contract is uniform — no conditional required-when-multiple rules to trip up implementations. Format is opaque — recommended values are short kebab-case slugs (`buyer-primary`, `audit-bus`, `dx-team`).",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    url: Annotated[
        AnyUrl,
        Field(
            description='Webhook endpoint URL. Same wire contract as `push-notification-config.url` — `format: "uri"`, no destination-port allowlist enforced by the protocol, SSRF protection via the IP-range check defined in docs/building/by-layer/L1/security.mdx#webhook-url-validation-ssrf. Sellers MUST validate URL syntax, HTTPS usage, hostname normalization, and reserved-range rejection when writing any config, including `active: false` configs. Sellers MUST complete an activation challenge or equivalent proof-of-control before treating a new or changed active subscriber as active.'
        ),
    ]
    event_types: Annotated[
        list[EventType],
        Field(
            description='Account-anchored notification types this subscriber wishes to receive on the registered `url`. The seller MUST NOT fire other types against this endpoint, and MUST NOT silently widen the filter when new account-anchored types are added. Creative lifecycle, assignment, indicator, account status, wholesale feed, reporting.delivery_ready, reporting.status_changed, and reporting.ledger_changed events are valid here; media-buy-anchored types (`scheduled`, `final`, `delayed`, `adjusted`, `window_update`, `impairment`) and agent-anchored types (`capabilities.changed`) are schema-invalid on this surface and sellers MUST reject those entries as per-account validation failures with `INVALID_REQUEST` or `VALIDATION_ERROR` and `error.field` pointing at the invalid `event_types` entry rather than silently dropping them.',
            min_length=1,
        ),
    ]
    product_payload_view: Annotated[
        ProductPayloadView | None,
        Field(
            description='Product webhook representation selected by this subscriber. Use canonical with lifecycle_tools.list_products; legacy is the default for 3.x get_products consumers. Sellers emit exactly canonical_product/canonical_pricing_options or product/pricing_options accordingly. Valid only when event_types includes a product.* event.'
        ),
    ] = ProductPayloadView.legacy
    authentication: Annotated[
        Authentication | None,
        Field(
            deprecated=True,
            description="Legacy authentication selector. Same precedence and semantics as `push-notification-config.authentication` — presence opts the seller into Bearer or HMAC-SHA256 signing; absence selects the default RFC 9421 webhook profile keyed off the seller's brand.json `agents[]` JWKS. The same signed-registration downgrade-resistance rules apply to accounts[].notification_configs[].authentication. Deprecated; removed in AdCP 4.0. Credentials are write-only and MUST NOT be echoed on `list_accounts` reads.",
        ),
    ] = None
    active: Annotated[
        StrictBool | None,
        Field(
            description="When false, the seller persists the configuration but suppresses fires. Use to pause a noisy subscriber without losing the registration. Sellers MUST NOT skip persisting the entry when `active: false` — the buyer's next `sync_accounts` MUST observe the same array, otherwise the buyer cannot distinguish pause from drop. Paused configs may skip only the outbound proof challenge while inactive; sellers MUST still enforce URL parsing, HTTPS, hostname normalization, and reserved-range rejection at write time. Reactivation requires full SSRF validation with connect pinning plus proof-of-control for any tuple without current valid proof."
        ),
    ] = True
    ext: ext_1.ExtensionObject | 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

Subclasses

  • adcp.types.projections._NotificationConfigResponse

Class variables

var active : bool | None
var authentication : Authentication | None
var event_types : list[EventType]
var ext : ExtensionObject | None
var model_config
var product_payload_view : ProductPayloadView | None
var subscriber_id : str
var url : pydantic.networks.AnyUrl

Inherited members

class NotificationType (*args, **kwds)
Expand source code
class NotificationType(StrEnum):
    product_created = 'product.created'
    product_updated = 'product.updated'
    product_priced = 'product.priced'
    product_removed = 'product.removed'
    signal_created = 'signal.created'
    signal_updated = 'signal.updated'
    signal_priced = 'signal.priced'
    signal_removed = 'signal.removed'
    wholesale_feed_bulk_change = 'wholesale_feed.bulk_change'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var product_created
var product_priced
var product_removed
var product_updated
var signal_created
var signal_priced
var signal_removed
var signal_updated
var wholesale_feed_bulk_change
class ObservedThrough (*args, **kwds)
Expand source code
class ObservedThrough(StrEnum):
    representative_consumer = 'representative_consumer'
    destination = 'destination'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var destination
var representative_consumer
class Offering (**data: Any)
Expand source code
class Offering(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    offering_id: Annotated[
        str,
        Field(
            description='Unique identifier for this offering. Used by hosts to reference specific offerings in si_get_offering calls.'
        ),
    ]
    name: Annotated[
        str,
        Field(
            description="Human-readable offering name (e.g., 'Winter Sale', 'Free Trial', 'Enterprise Platform')"
        ),
    ]
    description: Annotated[str | None, Field(description="Description of what's being offered")] = (
        None
    )
    tagline: Annotated[
        str | None, Field(description='Short promotional tagline for the offering')
    ] = None
    valid_from: Annotated[
        AwareDatetime | None,
        Field(
            description='When the offering becomes available. If not specified, offering is immediately available.'
        ),
    ] = None
    valid_to: Annotated[
        AwareDatetime | None,
        Field(
            description='When the offering expires. If not specified, offering has no expiration.'
        ),
    ] = None
    checkout_url: Annotated[
        AnyUrl | None,
        Field(
            description="URL for checkout/purchase flow when the brand doesn't support agentic checkout."
        ),
    ] = None
    landing_url: Annotated[
        AnyUrl | None,
        Field(
            description="Landing page URL for this offering. For catalog-driven creatives, this is the per-item click-through destination that platforms map to the ad's link-out URL. Every offering in a catalog should have a landing_url unless the format provides its own destination logic."
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description='Structured asset groups for this offering. Each group carries a typed pool of creative assets (headlines, images, videos, etc.) identified by a group ID that matches format-level vocabulary.'
        ),
    ] = None
    geo_targets: Annotated[
        GeoTargets | None,
        Field(
            description="Geographic scope of this offering. Declares where the offering is relevant — for location-specific offerings such as job vacancies, in-store promotions, or local events. Platforms use this to target geographically appropriate audiences and to filter out offerings irrelevant to a user's location. Uses the same geographic structures as targeting_overlay in create_media_buy."
        ),
    ] = None
    keywords: Annotated[
        list[str] | None,
        Field(
            description='Keywords for matching this offering to user intent. Hosts use these for retrieval/relevance scoring.'
        ),
    ] = None
    categories: Annotated[
        list[str] | None,
        Field(
            description="Categories this offering belongs to (e.g., 'measurement', 'identity', 'programmatic')"
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 assets : list[OfferingAssetGroup] | None
var categories : list[str] | None
var checkout_url : pydantic.networks.AnyUrl | None
var description : str | None
var ext : ExtensionObject | None
var geo_targets : GeoTargets | None
var keywords : list[str] | None
var landing_url : pydantic.networks.AnyUrl | None
var model_config
var name : str
var offering_id : str
var tagline : str | None
var valid_from : pydantic.types.AwareDatetime | None
var valid_to : pydantic.types.AwareDatetime | None

Inherited members

class OfferingAssetConstraint (**data: Any)
Expand source code
class OfferingAssetConstraint(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_group_id: Annotated[
        str,
        Field(
            description="The asset group this constraint applies to. Values are canonical-format vocabulary — each declaration chooses its own group IDs (e.g., 'headlines', 'images', 'videos'). Buyers discover them through Product.format_options[], publisher adagents.json formats[], or creative.supported_formats[] according to context."
        ),
    ]
    asset_type: Annotated[
        asset_content_type.AssetContentType,
        Field(description='The expected content type for this group.'),
    ]
    required: Annotated[
        StrictBool | None,
        Field(
            description='Whether this asset group must be present in each offering. Defaults to true.'
        ),
    ] = True
    min_count: Annotated[
        SchemaInt | None, Field(description='Minimum number of items required in this group.', ge=1)
    ] = None
    max_count: Annotated[
        SchemaInt | None, Field(description='Maximum number of items allowed in this group.', ge=1)
    ] = None
    asset_requirements: Annotated[
        asset_requirements_1.AssetRequirements | None,
        Field(
            description='Technical requirements for each item in this group (e.g., max_length for text, min_width/aspect_ratio for images). Applies uniformly to all items in the group.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 asset_group_id : str
var asset_requirements : ImageAssetRequirements | VideoAssetRequirements | AudioAssetRequirements | TextAssetRequirements | MarkdownAssetRequirements | HtmlAssetRequirements | CssAssetRequirements | JavascriptAssetRequirements | VastAssetRequirements | DaastAssetRequirements | UrlAssetRequirements | WebhookAssetRequirements | None
var asset_type : AssetContentType
var ext : ExtensionObject | None
var max_count : int | None
var min_count : int | None
var model_config
var required : bool | None

Inherited members

class OfferingAssetGroup (**data: Any)
Expand source code
class OfferingAssetGroup(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_group_id: Annotated[
        str,
        Field(
            description="Identifies the creative role this group fills. Values are defined by each canonical format declaration's offering_asset_constraints — not protocol constants. Discover creative-agent declarations via get_adcp_capabilities creative.supported_formats[] and sales-product declarations via Product.format_options[] (e.g., 'headlines', 'images', or 'videos')."
        ),
    ]
    asset_type: Annotated[
        asset_content_type.AssetContentType,
        Field(description='The content type of all items in this group.'),
    ]
    items: Annotated[
        list[Items],
        Field(
            description='The assets in this group. Each item carries an `asset_type` discriminator that selects the matching asset schema. Note: the group-level `asset_type` declares the expected type; individual items must also self-tag so validators can narrow errors. Intentionally excludes `brief-asset` and `catalog-asset` — those are campaign-input metadata types, not delivery-ready creative assets suitable for a pooled offering group. See core/assets/asset-union.json for the full asset-variant union.',
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 asset_group_id : str
var asset_type : AssetContentType
var ext : ExtensionObject | None
var items : list[TextAsset | ImageAsset | VideoAsset | AudioAsset | UrlAsset | HtmlAsset | MarkdownAsset | VastAsset | DaastAsset | CssAsset | JavascriptAsset | ZipAsset | WebhookAsset]
var model_config

Inherited members

class OohMetrics (**data: Any)
Expand source code
class OohMetrics(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    panels: Annotated[
        list[Panel] | None,
        Field(
            description="Panels (faces) covered by this row. A panel commonly carries multiple identifiers at once — OOH contracts key line items on the measurement-currency panel number AND the operator's own panel number together."
        ),
    ] = None
    posting_period_start: Annotated[
        date | None, Field(description='First in-charge date of the posting period this row covers')
    ] = None
    posting_period_end: Annotated[
        date | None, Field(description='Last date of the posting period this row covers')
    ] = None
    average_posted_date: Annotated[
        date | None,
        Field(
            description="Average actual posting date across the row's units — the date the display term runs from under OAAA Bulletin §2.2 / Poster §3.2(a) when materials were timely. Read with materials_timely to know whether that rule was in force."
        ),
    ] = None
    materials_timely: Annotated[
        StrictBool | None,
        Field(
            description="Seller's assertion that the buyer delivered acceptable materials by the contractual deadline, which determines whether the §2.2 posting-completion rule (term runs from average posting date) applied. An assertion about the buyer's delivery, not a derived value — it is not recomputable from postings[] evidence, and is the one field in this block that isn't checkable against it."
        ),
    ] = None
    share_of_voice_contracted: Annotated[
        StrictFloat | None,
        Field(
            description='Contracted share of voice where the buy is rotation-based (e.g., rotary bulletin programs) rather than an exclusive face, on a 0.0-1.0 scale. Share is time-weighted: the sum of contracted display durations divided by the full rotation duration. On equal-duration rotations this equals the slot-count ratio.',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    illuminated_hours: Annotated[
        StrictFloat | None,
        Field(
            description='Contracted daily illumination hours for the panels in this row. Determines the measured day-part basis (12/18/24-hour impressions) and the illumination-credit remedy when unmet.',
            ge=0.0,
            le=24.0,
        ),
    ] = None
    estimated_impressions: Annotated[
        SchemaInt | None,
        Field(
            description="Modeled audience impressions for the panels and period in this row. This is the channel's delivery number — there is no event-counted alternative. The methodology tier MUST be declared in estimation_basis; provider identity is declared in the row-level measurement_source; the billing vendor is declared in measurement_terms.billing_measurement. The row's top-level impressions SHOULD carry the same value so cross-channel aggregation works without channel-specific logic.",
            ge=0,
        ),
    ] = None
    estimation_basis: Annotated[
        EstimationBasis | None,
        Field(
            description="Methodology tier of estimated_impressions: currency_measured (an audience measurement currency's estimate for the panel and period — Geopath, Route, MOVE, COMMB — with the provider named in the row-level measurement_source) or seller_modeled (the seller's own model — the honest fallback for markets without a measurement currency). Tier, not provider: currencies change over time, so provider identity is data on measurement_source, not values in this enum."
        ),
    ] = None
    postings: Annotated[
        list[Posting] | None,
        Field(
            description='Posting records — the seller-attested settlement artifact proving each panel was posted for the period. Industry convention (OAAA model contracts, Proof of Performance §3.5): photo evidence per bulletin within five calendar days of posting and again after each rotary rotation; one representative close-up photograph per creative design variation for poster showings (no deadline attached). Distinct from the §2.2 posting-completion obligation (posting within five business days of the scheduled date), which governs average_posted_date, not evidence.'
        ),
    ] = None
    calculation_notes: Annotated[
        str | None,
        Field(
            description="Row-specific methodology context that doesn't fit the structured fields (e.g., a partial-period proration or a market-specific estimate adjustment). Same role as dooh_metrics.calculation_notes — canonical methodology declarations belong on the measurement vendor's discoverable surfaces, not here."
        ),
    ] = 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 average_posted_date : datetime.date | None
var calculation_notes : str | None
var estimated_impressions : int | None
var estimation_basis : EstimationBasis | None
var illuminated_hours : float | None
var materials_timely : bool | None
var model_config
var panels : list[Panel] | None
var posting_period_end : datetime.date | None
var posting_period_start : datetime.date | None
var postings : list[Posting] | None
var share_of_voice_contracted : float | None

Inherited members

class Operation (*args, **kwds)
Expand source code
class Operation(StrEnum):
    translate_to_native = 'translate_to_native'
    resolve_value = 'resolve_value'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var resolve_value
var translate_to_native
class OperationsContact (**data: Any)
Expand source code
class OperationsContact(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    url: Annotated[
        AnyUrl | None,
        Field(
            description='HTTPS page a human uses to open or track a reporting issue, such as a support portal or status page. Same hardened origin shape as the offering document URIs: never an IP literal, userinfo URL, loopback host, AdCP task endpoint, webhook target, or credentialed link.'
        ),
    ] = None
    email: Annotated[
        EmailStr | None,
        Field(
            description='Monitored operations mailbox for reporting escalations. A role address, not an individual.',
            max_length=254,
        ),
    ] = 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 email : pydantic.networks.EmailStr | None
var model_config
var url : pydantic.networks.AnyUrl | None

Inherited members

class Operator (*args, **kwds)
Expand source code
class Operator(StrEnum):
    any = 'any'
    none = 'none'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var any
var none
class OperatorIdentity (**data: Any)
Expand source code
class OperatorIdentity(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    operator: Annotated[
        str,
        Field(
            description="Domain of the entity operating on the brand's behalf. When the brand operates directly, this is the brand's domain.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    operator_unit: Annotated[
        operator_unit_1.OperatorUnit | None,
        Field(
            description='Optional operator-owned business unit, agency seat, or platform account. Its id participates in account identity; name is mutable display metadata. Omission from a complete desired replacement means the account should have no operator unit.'
        ),
    ] = 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 model_config
var operator : str
var operator_unit : OperatorUnit | None

Inherited members

class OperatorUnit (**data: Any)
Expand source code
class OperatorUnit(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    id: Annotated[
        str,
        Field(
            description='Stable identifier assigned by the operator. Numeric platform IDs and durable slugs are both valid. Scoped by the enclosing operator domain.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9][A-Za-z0-9._:/-]*$',
        ),
    ]
    name: Annotated[
        str | None,
        Field(
            description='Human-readable seat or business-unit name, such as Nova EMEA. This label may change and is not part of the natural account key.',
            max_length=200,
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var id : str
var model_config
var name : str | None

Inherited members

class OpportunityContext (**data: Any)
Expand source code
class OpportunityContext(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    opportunity_id: Annotated[
        str,
        Field(
            description='Opaque buyer-assigned identifier for this planning cycle, scoped to the seller and account.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    phase: Annotated[Phase | None, Field(description='Current stage of buyer planning.')] = None
    intent: Annotated[
        Intent | None,
        Field(description='How seriously the buyer is evaluating supply in this cycle.'),
    ] = None
    planning_horizon: Annotated[
        date_range.DateRange | None,
        Field(
            description='Inclusive calendar range in which the buyer expects the campaign to run.'
        ),
    ] = None
    response_deadline: Annotated[
        AwareDatetime | None,
        Field(description='Deadline by which the buyer needs a seller response.'),
    ] = None
    status: Annotated[
        Status | None,
        Field(
            description='Whether the planning cycle remains open. On calls after initial creation, omission means no status update and MUST NOT reopen or close the opportunity implicitly, except that successful create_media_buy proposal execution explicitly infers accepted closure.'
        ),
    ] = None
    close_reason: Annotated[
        CloseReason | None,
        Field(description='Why the opportunity closed. Required when status is closed.'),
    ] = None
    close_detail: Annotated[
        str | None,
        Field(
            description='Optional non-sensitive context about closure. MUST NOT identify a competitor or disclose confidential clearing terms.',
            max_length=500,
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var close_detail : str | None
var close_reason : CloseReason | None
var intent : Intent | None
var model_config
var opportunity_id : str
var phase : Phase | None
var planning_horizon : DateRange | None
var response_deadline : pydantic.types.AwareDatetime | None
var status : Status | None

Inherited members

class OptimizationGoal1 (**data: Any)
Expand source code
class OptimizationGoal1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['metric'] = 'metric'
    metric: Annotated[
        Metric,
        Field(
            description="Seller-native metric to optimize for. Delivery metrics: clicks (link clicks, swipe-throughs, CTA taps that navigate away), views (content views at the billable view threshold, as defined by delivery-metrics `views`; for viewability use viewable_rate), completed_views (video/audio completions — see view_duration_seconds), reach (unique audience reach — see reach_unit and target_frequency). Duration/score metrics: viewed_seconds (time in view per impression — reported back via `delivery-metrics.viewability.viewed_seconds`, governed by the viewability `standard`). Quality-rate metrics: viewable_rate (viewable / measurable impressions under the goal's `standard`; requires `standard`). Audience action metrics: engagements (any direct interaction with the ad unit beyond viewing — social reactions/comments/shares, story/unit opens, interactive overlay taps, companion banner interactions on audio and CTV), follows (new followers, page likes, artist/podcast/channel follows, or free channel/feed subscribes; paid subscriptions use event_type: subscribe), saves (saves, bookmarks, playlist adds, pins — signals of intent to return), profile_visits (visits to the brand's in-platform page — profile, artist page, channel, or storefront. Does not include external website clicks, which are covered by 'clicks'). **DEPRECATED values** (slated for removal at next major): `attention_seconds` and `attention_score` — these have no industry-graduated definition (DoubleVerify, IAS, Adelaide, TVision, Lumen each define them differently) and cannot be meaningfully optimized for without a vendor binding. Use `kind: 'vendor_metric'` with an explicit `vendor` and `metric_id` instead — that path binds the goal to a specific measurement vendor and reconciles to the same `(vendor, metric_id)` key in delivery's `vendor_metric_values[]`. Sellers MAY reject the deprecated values with `TERMS_REJECTED` and a suggestion to use the `vendor_metric` kind."
        ),
    ]
    standard: Annotated[
        viewability_standard.ViewabilityStandard | None,
        Field(
            description="Viewability standard the goal is judged against. Required when metric is 'viewable_rate'; optional for 'viewed_seconds' (seller default standard when omitted); not allowed for other metrics. Must be in metric_optimization.supported_viewability_standards when declared. A goal below a same-standard viewability performance_standard never relaxes that standard."
        ),
    ] = None
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description="Measurement vendor judging a viewable_rate or viewed_seconds goal; not allowed for other metrics. When omitted, the seller's default viewability measurement applies. Sellers MUST reject a vendor they cannot optimize against rather than substitute another."
        ),
    ] = None
    reach_unit: Annotated[
        reach_unit_1.ReachUnit | None,
        Field(
            description="Unit for reach measurement. Required when metric is 'reach'. Must be a value declared in the product's metric_optimization.supported_reach_units."
        ),
    ] = None
    target_frequency: Annotated[
        TargetFrequency | None,
        Field(
            description="Target frequency band for reach optimization. Only applicable when metric is 'reach'. Frames frequency as an optimization signal: the seller should treat impressions toward entities already within the [min, max] band as lower-value, and impressions toward unreached entities as higher-value. This shifts budget toward fresh reach rather than re-reaching known users. When omitted, the seller maximizes unique reach without a frequency constraint. A hard cap can still be layered via targeting_overlay.frequency_cap if a ceiling is needed."
        ),
    ] = None
    view_duration_seconds: Annotated[
        StrictFloat | None,
        Field(
            description="Minimum video view duration in seconds that qualifies as a completed_view for this goal. Only applicable when metric is 'completed_views'. When omitted, the seller uses their platform default (typically 2–15 seconds). Common values: 2 (Snap/LinkedIn default), 6 (TikTok), 15 (Snap 15-second views, Meta ThruPlay). Sellers declare which durations they support in metric_optimization.supported_view_durations. Sellers must reject goals with unsupported values — silent rounding would create measurement discrepancies.",
            gt=0.0,
        ),
    ] = None
    target: Annotated[
        Target | Target3 | None,
        Field(
            description='Target for this metric. When omitted, the seller optimizes for maximum metric volume within budget.',
            discriminator='kind',
        ),
    ] = None
    priority: Annotated[
        SchemaInt | None,
        Field(
            description='Relative priority among sibling goals. Lower numbers rank first. Goals without priority follow explicitly prioritized goals. Ties use array order, so the earliest goal at the lowest explicit priority is primary; when all priorities are omitted, the first goal is primary.',
            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

Subclasses

Class variables

var kind : Literal['metric']
var metric : Metric
var model_config
var priority : int | None
var reach_unit : ReachUnit | None
var standard : ViewabilityStandard | None
var target : Target | Target3 | None
var target_frequency : TargetFrequency | None
var vendor : BrandReference | None
var view_duration_seconds : float | None

Inherited members

class OptimizationGoal10 (**data: Any)
Expand source code
class OptimizationGoal10(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['vendor_metric'] = 'vendor_metric'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description='Vendor that defines and computes this metric. Same shape as `vendor_metric_values.vendor`, `reporting_capabilities.vendor_metrics[].vendor`, and `vendor_metric_optimization.supported_metrics[].vendor` — symmetric across discovery, capability, commitment, optimization, and reporting surfaces.'
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(
            description="Identifier for the metric within the vendor's vocabulary (e.g., `attention_score`, `attention_seconds`, `gco2e_per_impression`, `awareness_lift`). MUST be present in the vendor's published `measurement.metrics[]` catalog and in the product's `vendor_metric_optimization.supported_metrics[]`."
        ),
    ]
    target: Annotated[
        Target18 | Target19 | None,
        Field(
            description="Target for this vendor metric. When omitted, the seller optimizes for maximum metric volume / score within budget. `cost_per` and `threshold_rate` semantics mirror the same target kinds on the `metric` kind — units are vendor-defined and depend on the vendor's `measurement.metrics[]` declaration for this `metric_id`.",
            discriminator='kind',
        ),
    ] = None
    priority: Annotated[
        SchemaInt | None,
        Field(
            description='Relative priority among sibling goals. Lower numbers rank first. Goals without priority follow explicitly prioritized goals. Ties use array order, so the earliest goal at the lowest explicit priority is primary; when all priorities are omitted, the first goal is primary.',
            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

Class variables

var kind : Literal['vendor_metric']
var metric_id : VendorMetricId
var model_config
var priority : int | None
var target : Target18 | Target19 | None
var vendor : BrandReference

Inherited members

class OptimizationGoal2 (**data: Any)
Expand source code
class OptimizationGoal2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['event'] = 'event'
    event_sources: Annotated[
        list[EventSource],
        Field(
            description='Event source and type pairs that feed this goal. Each entry identifies a source and event type to include. When the seller supports multi_source_event_dedup (declared in get_adcp_capabilities), they deduplicate by event_id across all entries — the same business event from multiple sources counts once, using value_field and value_factor from the first matching entry. When multi_source_event_dedup is false or absent, buyers should use a single entry per goal; the seller will use only the first entry. All event sources must be configured via sync_event_sources.',
            min_length=1,
        ),
    ]
    target: Annotated[
        Target4 | Target5 | Target6 | None,
        Field(
            description='Target cost or return for this event goal. When omitted, the seller optimizes for maximum conversion count within budget — regardless of whether value_field is present on event sources. The presence of value_field alone does not change the optimization objective; it only makes value available for reporting. An explicit target of maximize_value or per_ad_spend is required to steer toward value.',
            discriminator='kind',
        ),
    ] = None
    attribution_window: Annotated[
        attribution_window_1.AttributionWindow | None,
        Field(
            description="Attribution window for this optimization goal — references the canonical `attribution-window` shape (post_click, post_view, model). Values must match an option declared in the seller's `conversion_tracking.attribution_windows` capability. Sellers MUST reject windows not in their declared capabilities. When the entire field is omitted, the seller uses their default window."
        ),
    ] = None
    priority: Annotated[
        SchemaInt | None,
        Field(
            description='Relative priority among sibling goals. Lower numbers rank first. Goals without priority follow explicitly prioritized goals. Ties use array order, so the earliest goal at the lowest explicit priority is primary; when all priorities are omitted, the first goal is primary.',
            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

Subclasses

Class variables

var attribution_window : AttributionWindow | None
var event_sources : list[EventSource]
var kind : Literal['adcp.types.domains.core.event']
var model_config
var priority : int | None
var target : Target4 | Target5 | Target6 | None

Inherited members

class OptimizationGoal3 (**data: Any)
Expand source code
class OptimizationGoal3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['vendor_metric'] = 'vendor_metric'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description='Vendor that defines and computes this metric. Same shape as `vendor_metric_values.vendor`, `reporting_capabilities.vendor_metrics[].vendor`, and `vendor_metric_optimization.supported_metrics[].vendor` — symmetric across discovery, capability, commitment, optimization, and reporting surfaces.'
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(
            description="Identifier for the metric within the vendor's vocabulary (e.g., `attention_score`, `attention_seconds`, `gco2e_per_impression`, `awareness_lift`). MUST be present in the vendor's published `measurement.metrics[]` catalog and in the product's `vendor_metric_optimization.supported_metrics[]`."
        ),
    ]
    target: Annotated[
        Target7 | Target8 | None,
        Field(
            description="Target for this vendor metric. When omitted, the seller optimizes for maximum metric volume / score within budget. `cost_per` and `threshold_rate` semantics mirror the same target kinds on the `metric` kind — units are vendor-defined and depend on the vendor's `measurement.metrics[]` declaration for this `metric_id`.",
            discriminator='kind',
        ),
    ] = None
    priority: Annotated[
        SchemaInt | None,
        Field(
            description='Relative priority among sibling goals. Lower numbers rank first. Goals without priority follow explicitly prioritized goals. Ties use array order, so the earliest goal at the lowest explicit priority is primary; when all priorities are omitted, the first goal is primary.',
            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

Subclasses

Class variables

var kind : Literal['vendor_metric']
var metric_id : VendorMetricId
var model_config
var priority : int | None
var target : Target7 | Target8 | None
var vendor : BrandReference

Inherited members

class OptimizationGoal4 (**data: Any)
Expand source code
class OptimizationGoal4(AdCPBaseModel):
    pass

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 model_config

Inherited members

class OptimizationGoal5 (**data: Any)
Expand source code
class OptimizationGoal5(OptimizationGoal1, OptimizationGoal4):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class OptimizationGoal6 (**data: Any)
Expand source code
class OptimizationGoal6(OptimizationGoal2, OptimizationGoal4):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class OptimizationGoal7 (**data: Any)
Expand source code
class OptimizationGoal7(OptimizationGoal3, OptimizationGoal4):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class OptimizationGoal8 (**data: Any)
Expand source code
class OptimizationGoal8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['metric'] = 'metric'
    metric: Annotated[
        Metric,
        Field(
            description="Seller-native metric to optimize for. Delivery metrics: clicks (link clicks, swipe-throughs, CTA taps that navigate away), views (content views at the billable view threshold, as defined by delivery-metrics `views`; for viewability use viewable_rate), completed_views (video/audio completions — see view_duration_seconds), reach (unique audience reach — see reach_unit and target_frequency). Duration/score metrics: viewed_seconds (time in view per impression — reported back via `delivery-metrics.viewability.viewed_seconds`, governed by the viewability `standard`). Quality-rate metrics: viewable_rate (viewable / measurable impressions under the goal's `standard`; requires `standard`). Audience action metrics: engagements (any direct interaction with the ad unit beyond viewing — social reactions/comments/shares, story/unit opens, interactive overlay taps, companion banner interactions on audio and CTV), follows (new followers, page likes, artist/podcast/channel follows, or free channel/feed subscribes; paid subscriptions use event_type: subscribe), saves (saves, bookmarks, playlist adds, pins — signals of intent to return), profile_visits (visits to the brand's in-platform page — profile, artist page, channel, or storefront. Does not include external website clicks, which are covered by 'clicks'). **DEPRECATED values** (slated for removal at next major): `attention_seconds` and `attention_score` — these have no industry-graduated definition (DoubleVerify, IAS, Adelaide, TVision, Lumen each define them differently) and cannot be meaningfully optimized for without a vendor binding. Use `kind: 'vendor_metric'` with an explicit `vendor` and `metric_id` instead — that path binds the goal to a specific measurement vendor and reconciles to the same `(vendor, metric_id)` key in delivery's `vendor_metric_values[]`. Sellers MAY reject the deprecated values with `TERMS_REJECTED` and a suggestion to use the `vendor_metric` kind."
        ),
    ]
    standard: Annotated[
        viewability_standard.ViewabilityStandard | None,
        Field(
            description="Viewability standard the goal is judged against. Required when metric is 'viewable_rate'; optional for 'viewed_seconds' (seller default standard when omitted); not allowed for other metrics. Must be in metric_optimization.supported_viewability_standards when declared. A goal below a same-standard viewability performance_standard never relaxes that standard."
        ),
    ] = None
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description="Measurement vendor judging a viewable_rate or viewed_seconds goal; not allowed for other metrics. When omitted, the seller's default viewability measurement applies. Sellers MUST reject a vendor they cannot optimize against rather than substitute another."
        ),
    ] = None
    reach_unit: Annotated[
        reach_unit_1.ReachUnit | None,
        Field(
            description="Unit for reach measurement. Required when metric is 'reach'. Must be a value declared in the product's metric_optimization.supported_reach_units."
        ),
    ] = None
    target_frequency: Annotated[
        TargetFrequency | None,
        Field(
            description="Target frequency band for reach optimization. Only applicable when metric is 'reach'. Frames frequency as an optimization signal: the seller should treat impressions toward entities already within the [min, max] band as lower-value, and impressions toward unreached entities as higher-value. This shifts budget toward fresh reach rather than re-reaching known users. When omitted, the seller maximizes unique reach without a frequency constraint. A hard cap can still be layered via targeting_overlay.frequency_cap if a ceiling is needed."
        ),
    ] = None
    view_duration_seconds: Annotated[
        StrictFloat | None,
        Field(
            description="Minimum video view duration in seconds that qualifies as a completed_view for this goal. Only applicable when metric is 'completed_views'. When omitted, the seller uses their platform default (typically 2–15 seconds). Common values: 2 (Snap/LinkedIn default), 6 (TikTok), 15 (Snap 15-second views, Meta ThruPlay). Sellers declare which durations they support in metric_optimization.supported_view_durations. Sellers must reject goals with unsupported values — silent rounding would create measurement discrepancies.",
            gt=0.0,
        ),
    ] = None
    target: Annotated[
        Target | Target14 | None,
        Field(
            description='Target for this metric. When omitted, the seller optimizes for maximum metric volume within budget.',
            discriminator='kind',
        ),
    ] = None
    priority: Annotated[
        SchemaInt | None,
        Field(
            description='Relative priority among sibling goals. Lower numbers rank first. Goals without priority follow explicitly prioritized goals. Ties use array order, so the earliest goal at the lowest explicit priority is primary; when all priorities are omitted, the first goal is primary.',
            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

Class variables

var kind : Literal['metric']
var metric : Metric
var model_config
var priority : int | None
var reach_unit : ReachUnit | None
var standard : ViewabilityStandard | None
var target : Target | Target14 | None
var target_frequency : TargetFrequency | None
var vendor : BrandReference | None
var view_duration_seconds : float | None

Inherited members

class OptimizationGoal9 (**data: Any)
Expand source code
class OptimizationGoal9(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['event'] = 'event'
    event_sources: Annotated[
        list[EventSource],
        Field(
            description='Event source and type pairs that feed this goal. Each entry identifies a source and event type to include. When the seller supports multi_source_event_dedup (declared in get_adcp_capabilities), they deduplicate by event_id across all entries — the same business event from multiple sources counts once, using value_field and value_factor from the first matching entry. When multi_source_event_dedup is false or absent, buyers should use a single entry per goal; the seller will use only the first entry. All event sources must be configured via sync_event_sources.',
            min_length=1,
        ),
    ]
    target: Annotated[
        Target15 | Target16 | Target17 | None,
        Field(
            description='Target cost or return for this event goal. When omitted, the seller optimizes for maximum conversion count within budget — regardless of whether value_field is present on event sources. The presence of value_field alone does not change the optimization objective; it only makes value available for reporting. An explicit target of maximize_value or per_ad_spend is required to steer toward value.',
            discriminator='kind',
        ),
    ] = None
    attribution_window: Annotated[
        attribution_window_1.AttributionWindow | None,
        Field(
            description="Attribution window for this optimization goal — references the canonical `attribution-window` shape (post_click, post_view, model). Values must match an option declared in the seller's `conversion_tracking.attribution_windows` capability. Sellers MUST reject windows not in their declared capabilities. When the entire field is omitted, the seller uses their default window."
        ),
    ] = None
    priority: Annotated[
        SchemaInt | None,
        Field(
            description='Relative priority among sibling goals. Lower numbers rank first. Goals without priority follow explicitly prioritized goals. Ties use array order, so the earliest goal at the lowest explicit priority is primary; when all priorities are omitted, the first goal is primary.',
            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

Class variables

var attribution_window : AttributionWindow | None
var event_sources : list[EventSource]
var kind : Literal['adcp.types.domains.core.event']
var model_config
var priority : int | None
var target : Target15 | Target16 | Target17 | None

Inherited members

class Option (**data: Any)
Expand source code
class Option(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    value: Annotated[
        Any, Field(description='The value the buyer passes in `config` for this field.')
    ]
    label: Annotated[str | None, Field(description='Human-readable label for this option.')] = None
    metadata: Annotated[
        dict[str, Any] | None,
        Field(
            description='Option-specific attributes the buyer can filter or display (e.g. for a voice: language, gender, provider, custom).'
        ),
    ] = 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 label : str | None
var metadata : dict[str, typing.Any] | None
var model_config
var value : Any

Inherited members

class OrderingEncoding (**data: Any)
Expand source code
class OrderingEncoding(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: Annotated[str, Field(max_length=128, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,128}$')]
    purpose: Literal['ordering_encoding'] = 'ordering_encoding'
    input_rows: Annotated[list[dict[str, Any]], Field(min_length=2)]
    canonical_utf8_base64: Annotated[
        str, Field(description='Base64 of the exact expected canonical UTF-8 bytes.', min_length=1)
    ]
    sha256: Annotated[str, Field(pattern='^[A-Fa-f0-9]{64}$')]

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 canonical_utf8_base64 : str
var input_rows : list[dict[str, typing.Any]]
var model_config
var name : str
var purpose : Literal['ordering_encoding']
var sha256 : str

Inherited members

class Outcome (*args, **kwds)
Expand source code
class Outcome(StrEnum):
    verified = 'verified'
    not_found = 'not_found'
    expired = 'expired'
    revoked = 'revoked'
    invalid = 'invalid'
    unsupported = 'unsupported'
    unverifiable = 'unverifiable'
    untrusted_issuer = 'untrusted_issuer'
    untrusted_resolver = 'untrusted_resolver'
    subject_mismatch = 'subject_mismatch'
    digest_mismatch = 'digest_mismatch'
    resolution_failed = 'resolution_failed'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var digest_mismatch
var expired
var invalid
var not_found
var resolution_failed
var revoked
var subject_mismatch
var unsupported
var untrusted_issuer
var untrusted_resolver
var unverifiable
var verified
class OutcomeMeasurement (**data: Any)
Expand source code
class OutcomeMeasurement(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[
        str,
        Field(
            description='Type of measurement',
            examples=['incremental_sales_lift', 'brand_lift', 'foot_traffic'],
        ),
    ]
    attribution: Annotated[
        str,
        Field(
            description='Attribution methodology',
            examples=['deterministic_purchase', 'probabilistic'],
        ),
    ]
    window: Annotated[
        duration.Duration | None,
        Field(
            description='Attribution window as a structured duration (e.g., {"interval": 30, "unit": "days"}).'
        ),
    ] = None
    reporting: Annotated[
        str,
        Field(
            description='Reporting frequency and format',
            examples=['weekly_dashboard', 'real_time_api'],
        ),
    ]

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 attribution : str
var model_config
var reporting : str
var type : str
var window : Duration | None

Inherited members

class OutcomeTargetCostPer (**data: Any)
Expand source code
class OutcomeTargetCostPer(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    amount: Annotated[
        StrictFloat,
        Field(
            description="Average cost amount per goal result, denominated in currency. The answered commercial_terms.bidding.cost_per.amount MUST be greater than or equal to it: the requested amount when it is plannable, otherwise the lowest plannable amount. An amount is plannable when the seller can forecast goal volume at or below (cap) or around (target) it within the buyer's budget, spending at least offer_filters.budget_range.min when present. When the planned spend at the answered amount is below commercial_terms.total_budget, each forecast point MUST carry metrics.spend. A seller MAY return additional proposals at higher amounts under the same strength to show what volume a higher cost buys.",
            gt=0.0,
        ),
    ]
    currency: Annotated[
        str,
        Field(
            description="ISO 4217 currency of amount. BiddingPolicy.cost_per has no currency because it inherits the media-buy currency, and no media buy exists at request time, so the request states it. It becomes the answer's currency: every answering proposal's purchases[].pricing.currency (which bidding amounts use) and forecast.currency MUST equal it, as MUST commercial_terms.total_budget.currency and total_budget_guidance.currency when present; sellers MUST NOT convert currency. It MUST equal offer_filters.budget_range.currency when present. The seller plans within budget_range.max when present, else at or above budget_range.min, and total_budget MUST NOT exceed max or fall below min. A seller rejects a conflict with budget_range, pricing_currencies, the account currency, or the requested products' pricing currencies with INVALID_REQUEST naming criteria.outcome_target.cost_per.",
            pattern='^[A-Z]{3}$',
        ),
    ]
    strength: Annotated[
        outcome_target_cost_strength.OutcomeTargetCostStrength,
        Field(
            description="BiddingPolicy.cost_per strength: `cap` optimizes for an average at or below the amount and accepts underdelivery when necessary; `target` optimizes around the amount while balancing volume and spend. Neither is a per-result or per-auction guarantee. The answer MUST keep this strength: a cap of 3 the seller can only meet at 4.50 returns {amount: 4.50, strength: 'cap'}, never 'target'. A seller that will not plan at any amount under this strength rejects instead."
        ),
    ]

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 amount : float
var currency : str
var model_config
var strength : OutcomeTargetCostStrength

Inherited members

class OutputCapabilityId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class OutputCapabilityId(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-zA-Z0-9_-]+$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class Overlay (**data: Any)
Expand source code
class Overlay(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    id: Annotated[
        str,
        Field(
            description="Identifier for this overlay (e.g., 'play_pause', 'volume', 'publisher_logo', 'carousel_prev', 'carousel_next')"
        ),
    ]
    description: Annotated[
        str | None,
        Field(
            description='Human-readable explanation of what this overlay is and how buyers should account for it'
        ),
    ] = None
    visual: Annotated[
        Visual | None,
        Field(
            description='Optional visual reference for this overlay element. Useful for creative agents compositing previews and for buyers understanding what will appear over their content. Must include at least one of: url, light, or dark.'
        ),
    ] = None
    bounds: Annotated[
        Bounds,
        Field(
            description="Position and size of the overlay relative to the asset's own top-left corner. See 'unit' for coordinate interpretation."
        ),
    ]

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 bounds : Bounds
var description : str | None
var id : str
var model_config
var visual : Visual | None

Inherited members

class Package (**data: Any)
Expand source code
class Package(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    package_id: Annotated[str, Field(description="Seller's unique identifier for the package")]
    product_id: Annotated[
        str | None,
        Field(
            description="ID of the product this package is based on. For packages created from an explicit create_media_buy package request, sellers MUST echo the request package's product_id on every response package object that represents that requested package."
        ),
    ] = None
    audience_evidence_selections: Annotated[
        list[audience_evidence_selection.AudienceEvidenceSelection] | None,
        Field(
            description='Exact immutable audience-evidence snapshots that affected recommendation, eligibility, or package construction. A confirmed package MUST include a package_construction selection matching every buyer audience_evidence_pin and every snapshot used to satisfy package audience_evidence_requirements; this readback remains mandatory on subsequent package read surfaces. This is decision provenance only; applied targeting remains exclusively in targeting_overlay and targeting_resolution.demographics.',
            min_length=1,
        ),
    ] = None
    budget: Annotated[
        StrictFloat | None,
        Field(
            description='Hard lifetime spend cap for this package in the media-buy currency. Every selected pricing option in an AdCP-authored media buy MUST declare that same currency. In seller-optimized allocation mode this is a ceiling, not a current allocation. May be omitted when the package is bounded only by the shared media-buy total.',
            ge=0.0,
        ),
    ] = None
    min_spend_target: Annotated[
        StrictFloat | None,
        Field(
            description='Soft lifetime spend target accepted for this package under seller-optimized budget allocation. This is an allocation preference, not a billing or delivery guarantee.',
            ge=0.0,
        ),
    ] = None
    daily_budget_cap: Annotated[
        StrictFloat | None,
        Field(
            description="The hard package spend ceiling per shared media-buy cap day, in the media buy's currency. Sellers MUST echo this whenever a package daily cap is set. It is a subordinate ceiling, not a reserved or current allocation; the media buy's budget_cap_timezone defines its day boundary.",
            ge=0.0,
        ),
    ] = None
    pacing: pacing_1.Pacing | None = None
    pricing_option_id: Annotated[
        str | None,
        Field(
            description="ID of the selected pricing option from the product's pricing_options array"
        ),
    ] = None
    bid_price: Annotated[
        StrictFloat | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy bidding representation. 3.2 sellers normalize accepted legacy input and SHOULD echo bidding instead. Removed in the next major.',
            ge=0.0,
        ),
    ] = None
    bidding: Annotated[
        bidding_policy.BiddingPolicy | None,
        Field(
            description='Package-authored bidding policy, echoed only when the buyer authored a package override. `{automatic:true}` is an explicit automatic-bidding override. Omission means the package inherits media-buy bidding or, when both scopes are absent, uses provider automatic delivery. Monetary fields are denominated in the media-buy currency. Sellers MUST NOT materialize inherited media-buy policy here.'
        ),
    ] = None
    price_breakdown: Annotated[
        price_breakdown_1.PriceBreakdown | None,
        Field(
            description="Breakdown of the effective price for this package. On fixed-price packages, echoes the pricing option's breakdown. On auction packages, shows the clearing price breakdown including any commission or settlement terms."
        ),
    ] = None
    impressions: Annotated[
        StrictFloat | None, Field(description='Impression goal for this package', ge=0.0)
    ] = None
    catalogs: Annotated[
        list[catalog.Catalog] | None,
        Field(
            description='Catalogs this package promotes. Each catalog MUST have a distinct type (e.g., one product catalog, one store catalog). This constraint is enforced at the application level — sellers MUST reject requests containing multiple catalogs of the same type with a validation_error. Echoed from the create_media_buy request.'
        ),
    ] = None
    format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Legacy named-format IDs supplied for this package on create_media_buy. Sellers SHOULD echo this field whenever the request included it, including dual-emission cases where `format_option_refs` was the winning selector, so read surfaces preserve the original wire contract. Omitted means the request did not carry legacy format_ids unless the seller cannot reconstruct legacy requests created before this field was persisted.',
        ),
    ] = None
    format_option_refs: Annotated[
        list[format_option_ref.FormatOptionReference] | None,
        Field(
            description='Structured 3.1+ format option references supplied for this package on create_media_buy. Sellers SHOULD echo this field whenever the request included it. Publisher-catalog-backed options are identified by `{ scope: "publisher", publisher_domain, format_option_id }`; product-local options are identified by `{ scope: "product", format_option_id }` and resolve only against this package\'s target product. Omitted means the request did not carry format_option_refs unless the seller cannot reconstruct legacy requests created before this field was persisted.',
            min_length=1,
        ),
    ] = None
    format_kind: Annotated[
        str | None,
        Field(
            description='Direct canonical selector supplied for this package on create_media_buy. Sellers SHOULD echo this field whenever the request included it, including informational-echo cases where `format_ids` was the winning selector, so read surfaces preserve the original wire contract.'
        ),
    ] = None
    params: Annotated[
        dict[str, Any] | None,
        Field(
            description='Parameters for the direct canonical selector in `format_kind`, echoed from the create_media_buy request whenever the request included it. Requires `format_kind`; omitted only when the request did not carry direct canonical params or when the seller cannot reconstruct legacy requests created before this field was persisted.'
        ),
    ] = None
    targeting_overlay: Annotated[
        targeting.TargetingOverlay | None,
        Field(
            description='Complete effective targeting accepted for this package, including targeting bound through configured product selection plus package-specific targeting. Sellers MUST echo an applied package frequency_cap independently from any MediaBuy root cap. Sellers MUST also echo placement, property, and collection selection so buyers can audit purchased inventory: placements via placement_selection, collections via collection_selection (the committed concrete selectors, materialized even when the selection was produced through collection_list references).'
        ),
    ] = None
    targeting_resolution: Annotated[
        package_targeting_resolution.PackageTargetingResolution | None,
        Field(
            description="Execution details for the package's accepted targeting. Sellers MUST include targeting_resolution.demographics whenever demographic targeting was requested or applied."
        ),
    ] = None
    measurement_terms: Annotated[
        measurement_terms_1.MeasurementTerms | None,
        Field(
            description="Agreed billing measurement and makegood terms for this package. Reflects what was negotiated — may differ from the buyer's proposal or the product's defaults. When present, these terms are binding for the package's duration."
        ),
    ] = None
    performance_standards: Annotated[
        list[performance_standard.PerformanceStandard] | None,
        Field(
            description='Agreed performance standards for this package. When any entry specifies a vendor, creatives assigned to this package MUST include corresponding tracker_script or tracker_pixel assets from that vendor.',
            min_length=1,
        ),
    ] = None
    committed_metrics: Annotated[
        list[committed_metric.CommittedMetric] | None,
        Field(
            description="The binding reporting contract for this package — what the seller has agreed to populate in delivery reports. Each entry carries an explicit `committed_at` timestamp, so the array also serves as the contract amendment ledger: day-1 commitments share `committed_at = create_media_buy.confirmed_at`; mid-flight additions carry their own timestamps. When `create_media_buy.confirmed_at` is null for a provisional buy, sellers MUST omit `committed_metrics` until commitment. The first response that sets `confirmed_at` MAY include the initial committed-metrics set, and each such entry's `committed_at` MUST equal `confirmed_at`. The `missing_metrics` field on `get_media_buy_delivery` reconciles against this list, filtering to entries where `committed_at < reporting_period.end` (a metric committed mid-flight is only audited from its commitment timestamp forward). Sellers stamp the day-1 set on the `create_media_buy` response; mid-flight additions are appended via `update_media_buy` (append-only — sellers MUST reject attempts to modify or remove existing entries with `validation_error`, suggested code: `IMMUTABLE_FIELD`). Optional in v1; absence means the seller does not provide an audit-grade contract and `missing_metrics` falls back to the product's live `available_metrics` (a known audit gap — buyers SHOULD treat absence as 'no audit-grade contract' rather than 'clean delivery'). Each entry uses an explicit `scope` discriminator: `standard` for entries from the closed `available-metric.json` enum, `vendor` for vendor-defined metrics anchored on a BrandRef. Standard entries are symmetric with `by_package[].metric_values`; vendor entries reconcile to `by_package[].vendor_metric_values`; both use `by_package[].missing_metrics` for gaps. The atomic key remains `(scope, metric_id, qualifier)`, with vendor identity included for vendor scope. Replaces the parallel-array design that shipped briefly in #3510.",
            examples=[
                [
                    {
                        'scope': 'standard',
                        'metric_id': 'impressions',
                        'committed_at': '2026-04-29T10:53:00Z',
                    },
                    {
                        'scope': 'standard',
                        'metric_id': 'spend',
                        'committed_at': '2026-04-29T10:53:00Z',
                    },
                    {
                        'scope': 'standard',
                        'metric_id': 'completed_views',
                        'committed_at': '2026-04-29T10:53:00Z',
                    },
                    {
                        'scope': 'vendor',
                        'vendor': {'domain': 'attentionvendor.example'},
                        'metric_id': 'attention_units',
                        'committed_at': '2026-04-29T10:53:00Z',
                    },
                    {
                        'scope': 'standard',
                        'metric_id': 'viewable_rate',
                        'qualifier': {'viewability_standard': 'mrc'},
                        'committed_at': '2026-05-30T14:22:00Z',
                    },
                ]
            ],
            min_length=1,
        ),
    ] = None
    creative_assignments: Annotated[
        list[creative_assignment.CreativeAssignment] | None,
        Field(
            description='Creative assets assigned to this package, including the committed package-scoped rotation policy. Omitted rotation_mode reads as weighted for backward compatibility; all assignments resolve to one effective mode, and sequential positions are unique within each package-local group.'
        ),
    ] = None
    formats_to_provide: Annotated[
        list[package_format_snapshot.PackageFormatSnapshot] | None,
        Field(
            description='Immutable canonical creative contracts established for this package. Each entry is a PackageFormatSnapshot of the selected effective Product format declaration. A package whose selected format carries tracker_execution_contract MUST retain and return this checklist even after creative coverage is complete; the live Product is never substituted for the package snapshot.',
            min_length=1,
        ),
    ] = None
    formats_pending: Annotated[
        list[package_format_snapshot.PackageFormatSnapshot] | None,
        Field(
            description='PackageFormatSnapshot entries from formats_to_provide that do not yet have creative coverage through sync_creatives or inline assignment. Every entry MUST equal its formats_to_provide snapshot after RFC 8785 canonicalization and, when product_snapshot_digest is present, carry the identical digest. An empty emitted array means every required format is covered. Absence means readiness was not reported.'
        ),
    ] = None
    format_ids_to_provide: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format projection of formats_to_provide retained for older 3.x peers. New sellers emit canonical formats_to_provide declarations.',
        ),
    ] = None
    format_ids_pending: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format projection of formats_pending retained for older 3.x peers. New sellers emit canonical formats_pending declarations. An empty emitted array means every projected requirement is covered. Absence means legacy readiness was not reported and MUST NOT be interpreted as full coverage.',
        ),
    ] = None
    optimization_goals: Annotated[
        list[optimization_goal.OptimizationGoal] | None,
        Field(
            description='Optimization targets for this package. The seller optimizes delivery toward these goals in priority order. Common pattern: event goals (purchase, install) as primary targets at priority 1; metric goals (clicks, views) as secondary proxy signals at priority 2+.',
            min_length=1,
        ),
    ] = None
    start_time: Annotated[
        AwareDatetime | None,
        Field(
            description="Flight start date/time for this package in ISO 8601 format. When omitted, the package inherits the media buy's start_time. Sellers SHOULD always include the resolved value in responses, even when inherited."
        ),
    ] = None
    end_time: Annotated[
        AwareDatetime | None,
        Field(
            description="Flight end date/time for this package in ISO 8601 format. When omitted, the package inherits the media buy's end_time. Sellers SHOULD always include the resolved value in responses, even when inherited."
        ),
    ] = None
    paused: Annotated[
        StrictBool | None,
        Field(
            description='Whether this package is paused by the buyer. Paused packages do not deliver impressions. Defaults to false.'
        ),
    ] = False
    canceled: Annotated[
        StrictBool | None,
        Field(
            description='Whether this package has been canceled. Canceled packages stop delivery and cannot be reactivated. Defaults to false.'
        ),
    ] = False
    cancellation: Annotated[
        Cancellation | None,
        Field(description='Cancellation metadata. Present only when canceled is true.'),
    ] = None
    agency_estimate_number: Annotated[
        str | None,
        Field(
            description="Agency estimate or authorization number for this package. Echoed from the buyer's request. When present on the package, takes precedence over the media buy-level estimate number.",
            max_length=100,
        ),
    ] = None
    creative_deadline: Annotated[
        AwareDatetime | None,
        Field(
            description="ISO 8601 timestamp for creative upload or change deadline for this package. After this deadline, creative changes are rejected. When absent, the media buy's creative_deadline applies."
        ),
    ] = None
    context: Annotated[
        context_1.ContextObject | None,
        Field(
            description='Opaque package-level correlation data echoed unchanged in responses, webhooks, and read surfaces. Buyers targeting mixed seller populations SHOULD include a per-package correlation value here, commonly context.buyer_ref, so responses from legacy sellers that do not echo product_id can still be mapped back to the requested product or line item. Sellers MUST preserve this object unchanged and MUST NOT parse it for business logic.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var agency_estimate_number : str | None
var audience_evidence_selections : list[AudienceEvidenceSelection] | None
var bid_price : float | None
var bidding : BiddingPolicy | None
var budget : float | None
var canceled : bool | None
var cancellation : Cancellation | None
var catalogs : list[Catalog] | None
var committed_metrics : list[CommittedMetric1 | CommittedMetric2] | None
var context : ContextObject | None
var creative_assignments : list[CreativeAssignment] | None
var creative_deadline : pydantic.types.AwareDatetime | None
var daily_budget_cap : float | None
var end_time : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var format_ids : list[FormatReferenceStructuredObject] | None
var format_ids_pending : list[FormatReferenceStructuredObject] | None
var format_ids_to_provide : list[FormatReferenceStructuredObject] | None
var format_kind : str | None
var format_option_refs : list[FormatOptionReference1 | FormatOptionReference2] | None
var formats_pending : list[PackageFormatSnapshot18 | PackageFormatSnapshot19 | PackageFormatSnapshot20 | PackageFormatSnapshot21 | PackageFormatSnapshot22 | PackageFormatSnapshot23 | PackageFormatSnapshot24 | PackageFormatSnapshot25 | PackageFormatSnapshot26 | PackageFormatSnapshot27 | PackageFormatSnapshot28 | PackageFormatSnapshot29 | PackageFormatSnapshot30 | PackageFormatSnapshot31 | PackageFormatSnapshot32 | PackageFormatSnapshot33] | None
var formats_to_provide : list[PackageFormatSnapshot18 | PackageFormatSnapshot19 | PackageFormatSnapshot20 | PackageFormatSnapshot21 | PackageFormatSnapshot22 | PackageFormatSnapshot23 | PackageFormatSnapshot24 | PackageFormatSnapshot25 | PackageFormatSnapshot26 | PackageFormatSnapshot27 | PackageFormatSnapshot28 | PackageFormatSnapshot29 | PackageFormatSnapshot30 | PackageFormatSnapshot31 | PackageFormatSnapshot32 | PackageFormatSnapshot33] | None
var impressions : float | None
var measurement_terms : MeasurementTerms | None
var min_spend_target : float | None
var model_config
var optimization_goals : list[OptimizationGoal8 | OptimizationGoal9 | OptimizationGoal10] | None
var pacing : Pacing | None
var package_id : str
var params : dict[str, typing.Any] | None
var paused : bool | None
var performance_standards : list[PerformanceStandard] | None
var price_breakdown : PriceBreakdown | None
var pricing_option_id : str | None
var product_id : str | None
var start_time : pydantic.types.AwareDatetime | None
var targeting_overlay : TargetingOverlay | None
var targeting_resolution : PackageTargetingResolution | None

Inherited members

class PackageDeliveryMetricValue (**data: Any)
Expand source code
class PackageDeliveryMetricValue(Field0):
    qualifier: Annotated[
        Qualifier,
        Field(
            description="Qualifier keys disambiguating this row from sibling rows under the same `metric_id`. Symmetric with `committed_metrics.qualifier` today; expected to diverge in future minors as transparency disclosures buyers don't commit to ship delivery-only. Closed (`additionalProperties: false`) — new qualifier keys ship explicitly."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var qualifier : Qualifier

Inherited members

class PackageFormatSnapshot1 (**data: Any)
Expand source code
class PackageFormatSnapshot1(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image'] = 'image'
    params: image.CanonicalFormatImage

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImage
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot10 (**data: Any)
Expand source code
class PackageFormatSnapshot10(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['sponsored_placement'] = 'sponsored_placement'
    params: sponsored_placement.CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['sponsored_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot11 (**data: Any)
Expand source code
class PackageFormatSnapshot11(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['native_in_feed'] = 'native_in_feed'
    params: native_in_feed.CanonicalFormatNativeInFeed

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['native_in_feed']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatNativeInFeed
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot12 (**data: Any)
Expand source code
class PackageFormatSnapshot12(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['responsive_creative'] = 'responsive_creative'
    params: responsive_creative.CanonicalFormatResponsiveCreative

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['responsive_creative']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatResponsiveCreative
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot13 (**data: Any)
Expand source code
class PackageFormatSnapshot13(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['agent_placement'] = 'agent_placement'
    params: agent_placement.CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['agent_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot14 (**data: Any)
Expand source code
class PackageFormatSnapshot14(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['seller_rendered_stateful_display'] = 'seller_rendered_stateful_display'
    params: seller_rendered_stateful_display.CanonicalFormatSellerRenderedStatefulDisplay

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['seller_rendered_stateful_display']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSellerRenderedStatefulDisplay
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot15 (**data: Any)
Expand source code
class PackageFormatSnapshot15(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['coordinated_placements'] = 'coordinated_placements'
    params: coordinated_placements.CanonicalFormatCoordinatedPlacements

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['coordinated_placements']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatCoordinatedPlacements
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot16 (**data: Any)
Expand source code
class PackageFormatSnapshot16(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['custom'] = 'custom'
    params: Annotated[
        dict[str, Any],
        Field(
            description="Custom shape's params. Validated against the schema fetched from `format_schema.uri` at the cached `format_schema.digest`."
        ),
    ]

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['custom']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : dict[str, typing.Any]
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot17 (**data: Any)
Expand source code
class PackageFormatSnapshot17(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Any
    params: Any

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Any
var model_config
var params : Any
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot18 (**data: Any)
Expand source code
class PackageFormatSnapshot18(PackageFormatSnapshot1):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['image'] = 'image'
    params: image.CanonicalFormatImage

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['image']
var model_config
var params : CanonicalFormatImage
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot19 (**data: Any)
Expand source code
class PackageFormatSnapshot19(PackageFormatSnapshot2):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['html5'] = 'html5'
    params: html5.CanonicalFormatHtml5Banner

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['html5']
var model_config
var params : CanonicalFormatHtml5Banner
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot2 (**data: Any)
Expand source code
class PackageFormatSnapshot2(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['html5'] = 'html5'
    params: html5.CanonicalFormatHtml5Banner

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['html5']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHtml5Banner
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot20 (**data: Any)
Expand source code
class PackageFormatSnapshot20(PackageFormatSnapshot3):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['display_tag'] = 'display_tag'
    params: display_tag.CanonicalFormatDisplayTag

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['display_tag']
var model_config
var params : CanonicalFormatDisplayTag
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot21 (**data: Any)
Expand source code
class PackageFormatSnapshot21(PackageFormatSnapshot4):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['image_carousel'] = 'image_carousel'
    params: image_carousel.CanonicalFormatImageCarousel

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['image_carousel']
var model_config
var params : CanonicalFormatImageCarousel
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot22 (**data: Any)
Expand source code
class PackageFormatSnapshot22(PackageFormatSnapshot5):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['video_hosted'] = 'video_hosted'
    params: video_hosted.CanonicalFormatHostedVideo

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['video_hosted']
var model_config
var params : CanonicalFormatHostedVideo
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot23 (**data: Any)
Expand source code
class PackageFormatSnapshot23(PackageFormatSnapshot6):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['video_vast'] = 'video_vast'
    params: video_vast.CanonicalFormatVastVideo

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['video_vast']
var model_config
var params : CanonicalFormatVastVideo
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot24 (**data: Any)
Expand source code
class PackageFormatSnapshot24(PackageFormatSnapshot7):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['audio_hosted'] = 'audio_hosted'
    params: audio_hosted.CanonicalFormatHostedAudio

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['audio_hosted']
var model_config
var params : CanonicalFormatHostedAudio
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot25 (**data: Any)
Expand source code
class PackageFormatSnapshot25(PackageFormatSnapshot8):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['audio_vast'] = 'audio_vast'
    params: audio_vast.CanonicalFormatVastAudio

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['audio_vast']
var model_config
var params : CanonicalFormatVastAudio
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot26 (**data: Any)
Expand source code
class PackageFormatSnapshot26(PackageFormatSnapshot9):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['audio_daast'] = 'audio_daast'
    params: audio_daast.CanonicalFormatDaastAudio

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['audio_daast']
var model_config
var params : CanonicalFormatDaastAudio
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot27 (**data: Any)
Expand source code
class PackageFormatSnapshot27(PackageFormatSnapshot10):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['sponsored_placement'] = 'sponsored_placement'
    params: sponsored_placement.CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['sponsored_placement']
var model_config
var params : CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot28 (**data: Any)
Expand source code
class PackageFormatSnapshot28(PackageFormatSnapshot11):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['native_in_feed'] = 'native_in_feed'
    params: native_in_feed.CanonicalFormatNativeInFeed

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['native_in_feed']
var model_config
var params : CanonicalFormatNativeInFeed
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot29 (**data: Any)
Expand source code
class PackageFormatSnapshot29(PackageFormatSnapshot12):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['responsive_creative'] = 'responsive_creative'
    params: responsive_creative.CanonicalFormatResponsiveCreative

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['responsive_creative']
var model_config
var params : CanonicalFormatResponsiveCreative
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot3 (**data: Any)
Expand source code
class PackageFormatSnapshot3(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['display_tag'] = 'display_tag'
    params: display_tag.CanonicalFormatDisplayTag

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['display_tag']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDisplayTag
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot30 (**data: Any)
Expand source code
class PackageFormatSnapshot30(PackageFormatSnapshot13):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['agent_placement'] = 'agent_placement'
    params: agent_placement.CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['agent_placement']
var model_config
var params : CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot31 (**data: Any)
Expand source code
class PackageFormatSnapshot31(PackageFormatSnapshot14):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['seller_rendered_stateful_display'] = 'seller_rendered_stateful_display'
    params: seller_rendered_stateful_display.CanonicalFormatSellerRenderedStatefulDisplay

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['seller_rendered_stateful_display']
var model_config
var params : CanonicalFormatSellerRenderedStatefulDisplay
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot32 (**data: Any)
Expand source code
class PackageFormatSnapshot32(PackageFormatSnapshot15):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['coordinated_placements'] = 'coordinated_placements'
    params: coordinated_placements.CanonicalFormatCoordinatedPlacements

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['coordinated_placements']
var model_config
var params : CanonicalFormatCoordinatedPlacements
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot33 (**data: Any)
Expand source code
class PackageFormatSnapshot33(PackageFormatSnapshot16):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str | None,
        Field(
            description='Product whose effective selected format was snapshotted. Required whenever tracker_execution_contract is present.',
            min_length=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Nonempty, duplicate-free effective placement set, sorted by publisher_domain then placement_id using ascending UTF-8 bytes without Unicode normalization. Omission binds the product-wide common effective contract; it never means an inferred list of all current placements.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for first-class VAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for first-class DAAST tracker matching when no sibling delivery document supplies one. The value is immutable for the package.'
        ),
    ] = None
    tracker_execution_contract_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 canonical JSON for tracker_execution_contract alone. Required if and only if the snapshot contains that contract.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    product_snapshot_digest: Annotated[
        str | None,
        Field(
            description="Immutable SHA-256 digest of the package format snapshot's closed product-binding preimage. Required for every contract-bearing snapshot and paired with product_id whenever present.",
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    format_kind: Literal['custom'] = 'custom'
    params: Annotated[dict[str, Any], Field(description="Custom shape's params. Validated against the schema fetched from `format_schema.uri` at the cached `format_schema.digest`.")]

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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_kind : Literal['custom']
var model_config
var params : dict[str, typing.Any]
var placement_refs : list[PlacementReference] | None
var product_id : str | None
var product_snapshot_digest : str | None
var tracker_execution_contract_digest : str | None

Inherited members

class PackageFormatSnapshot4 (**data: Any)
Expand source code
class PackageFormatSnapshot4(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image_carousel'] = 'image_carousel'
    params: image_carousel.CanonicalFormatImageCarousel

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image_carousel']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImageCarousel
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot5 (**data: Any)
Expand source code
class PackageFormatSnapshot5(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_hosted'] = 'video_hosted'
    params: video_hosted.CanonicalFormatHostedVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot6 (**data: Any)
Expand source code
class PackageFormatSnapshot6(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_vast'] = 'video_vast'
    params: video_vast.CanonicalFormatVastVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot7 (**data: Any)
Expand source code
class PackageFormatSnapshot7(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_hosted'] = 'audio_hosted'
    params: audio_hosted.CanonicalFormatHostedAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot8 (**data: Any)
Expand source code
class PackageFormatSnapshot8(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_vast'] = 'audio_vast'
    params: audio_vast.CanonicalFormatVastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageFormatSnapshot9 (**data: Any)
Expand source code
class PackageFormatSnapshot9(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_daast'] = 'audio_daast'
    params: audio_daast.CanonicalFormatDaastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_daast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDaastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class PackageSignalTargeting1 (**data: Any)
Expand source code
class PackageSignalTargeting1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[signal_ref_1.SignalRef, Field(description='Named signal being targeted.')]
    value_type: Annotated[Literal['binary'], Field(description='Discriminator for binary signals.')] = 'binary'
    value: Annotated[
        Literal[True],
        Field(
            description='Binary package signal entries match users for whom the signal is true. Use the parent group operator for include/exclude.'
        ),
    ]

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 model_config
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3
var value : Literal[True]
var value_type : Literal['binary']

Inherited members

class PackageSignalTargeting2 (**data: Any)
Expand source code
class PackageSignalTargeting2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[signal_ref_1.SignalRef, Field(description='Named signal being targeted.')]
    value_type: Annotated[
        Literal['categorical'], Field(description='Discriminator for categorical signals.')
    ] = 'categorical'
    values: Annotated[
        list[str],
        Field(
            description='Values to target. Users with any of these values match the expression.',
            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

Subclasses

Class variables

var model_config
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3
var value_type : Literal['categorical']
var values : list[str]

Inherited members

class PackageSignalTargeting3 (**data: Any)
Expand source code
class PackageSignalTargeting3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[signal_ref_1.SignalRef, Field(description='Named signal being targeted.')]
    value_type: Annotated[
        Literal['numeric'], Field(description='Discriminator for numeric signals.')
    ] = 'numeric'
    min_value: Annotated[
        StrictFloat | None,
        Field(
            description="Minimum value, inclusive. Omit for no minimum. Should be within the signal definition's range when declared."
        ),
    ] = None
    max_value: Annotated[
        StrictFloat | None,
        Field(
            description="Maximum value, inclusive. Omit for no maximum. Should be within the signal definition's range when declared."
        ),
    ] = 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 max_value : float | None
var min_value : float | None
var model_config
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3
var value_type : Literal['numeric']

Inherited members

class PackageSignalTargeting4 (**data: Any)
Expand source code
class PackageSignalTargeting4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    pricing_option_id: Annotated[
        str | None,
        Field(
            description="Pricing option selected for this signal. Use the pricing_option_id from the product's signal_targeting_options entry when product-scoped pricing is present; otherwise use the seller get_signals pricing only when the product option does not override it. Required when the selected signal has pricing_options; omit only when the signal is bundled into the product price or has no incremental cost."
        ),
    ] = None
    signal_agent_segment_id: Annotated[
        str | None,
        Field(
            description='Optional opaque resolved-segment or seller execution handle for this signal. Omit when signal_ref plus the value expression is sufficient for the seller to resolve the signal. Include when the product option exposes a separate runtime or activation handle, and pass it verbatim. Buyers SHOULD prefer an exposed segment handle over reconstructing condition identity from categorical values because the handle can carry provider namespace and methodology distinctions.'
        ),
    ] = None
    activation_key: Annotated[
        activation_key_1.ActivationKey | None,
        Field(
            description='Destination-specific activation key returned by get_signals or activate_signal. Usually omitted for seller-offered signals selected directly through the same seller; include only when the selected signal was separately activated and the seller requires the activation key to correlate the package selection.'
        ),
    ] = 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 activation_key : ActivationKey1 | ActivationKey2 | None
var model_config
var pricing_option_id : str | None
var signal_agent_segment_id : str | None

Inherited members

class PackageSignalTargeting5 (**data: Any)
Expand source code
class PackageSignalTargeting5(PackageSignalTargeting1, PackageSignalTargeting4):
    model_config = ConfigDict(
        extra='allow',
    )
    pricing_option_id: Annotated[
        str | None,
        Field(
            description="Pricing option selected for this signal. Use the pricing_option_id from the product's signal_targeting_options entry when product-scoped pricing is present; otherwise use the seller get_signals pricing only when the product option does not override it. Required when the selected signal has pricing_options; omit only when the signal is bundled into the product price or has no incremental cost."
        ),
    ] = None
    signal_agent_segment_id: Annotated[
        str | None,
        Field(
            description='Optional opaque resolved-segment or seller execution handle for this signal. Omit when signal_ref plus the value expression is sufficient for the seller to resolve the signal. Include when the product option exposes a separate runtime or activation handle, and pass it verbatim. Buyers SHOULD prefer an exposed segment handle over reconstructing condition identity from categorical values because the handle can carry provider namespace and methodology distinctions.'
        ),
    ] = None
    activation_key: Annotated[
        activation_key_1.ActivationKey | None,
        Field(
            description='Destination-specific activation key returned by get_signals or activate_signal. Usually omitted for seller-offered signals selected directly through the same seller; include only when the selected signal was separately activated and the seller requires the activation key to correlate the package selection.'
        ),
    ] = 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 activation_key : ActivationKey1 | ActivationKey2 | None
var model_config
var pricing_option_id : str | None
var signal_agent_segment_id : str | None

Inherited members

class PackageSignalTargeting6 (**data: Any)
Expand source code
class PackageSignalTargeting6(PackageSignalTargeting2, PackageSignalTargeting4):
    model_config = ConfigDict(
        extra='allow',
    )
    pricing_option_id: Annotated[
        str | None,
        Field(
            description="Pricing option selected for this signal. Use the pricing_option_id from the product's signal_targeting_options entry when product-scoped pricing is present; otherwise use the seller get_signals pricing only when the product option does not override it. Required when the selected signal has pricing_options; omit only when the signal is bundled into the product price or has no incremental cost."
        ),
    ] = None
    signal_agent_segment_id: Annotated[
        str | None,
        Field(
            description='Optional opaque resolved-segment or seller execution handle for this signal. Omit when signal_ref plus the value expression is sufficient for the seller to resolve the signal. Include when the product option exposes a separate runtime or activation handle, and pass it verbatim. Buyers SHOULD prefer an exposed segment handle over reconstructing condition identity from categorical values because the handle can carry provider namespace and methodology distinctions.'
        ),
    ] = None
    activation_key: Annotated[
        activation_key_1.ActivationKey | None,
        Field(
            description='Destination-specific activation key returned by get_signals or activate_signal. Usually omitted for seller-offered signals selected directly through the same seller; include only when the selected signal was separately activated and the seller requires the activation key to correlate the package selection.'
        ),
    ] = 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 activation_key : ActivationKey1 | ActivationKey2 | None
var model_config
var pricing_option_id : str | None
var signal_agent_segment_id : str | None

Inherited members

class PackageSignalTargeting7 (**data: Any)
Expand source code
class PackageSignalTargeting7(PackageSignalTargeting3, PackageSignalTargeting4):
    model_config = ConfigDict(
        extra='allow',
    )
    pricing_option_id: Annotated[
        str | None,
        Field(
            description="Pricing option selected for this signal. Use the pricing_option_id from the product's signal_targeting_options entry when product-scoped pricing is present; otherwise use the seller get_signals pricing only when the product option does not override it. Required when the selected signal has pricing_options; omit only when the signal is bundled into the product price or has no incremental cost."
        ),
    ] = None
    signal_agent_segment_id: Annotated[
        str | None,
        Field(
            description='Optional opaque resolved-segment or seller execution handle for this signal. Omit when signal_ref plus the value expression is sufficient for the seller to resolve the signal. Include when the product option exposes a separate runtime or activation handle, and pass it verbatim. Buyers SHOULD prefer an exposed segment handle over reconstructing condition identity from categorical values because the handle can carry provider namespace and methodology distinctions.'
        ),
    ] = None
    activation_key: Annotated[
        activation_key_1.ActivationKey | None,
        Field(
            description='Destination-specific activation key returned by get_signals or activate_signal. Usually omitted for seller-offered signals selected directly through the same seller; include only when the selected signal was separately activated and the seller requires the activation key to correlate the package selection.'
        ),
    ] = 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 activation_key : ActivationKey1 | ActivationKey2 | None
var model_config
var pricing_option_id : str | None
var signal_agent_segment_id : str | None

Inherited members

class PackageSignalTargetingGroup (**data: Any)
Expand source code
class PackageSignalTargetingGroup(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    operator: Annotated[
        Operator,
        Field(
            description="How to evaluate the signals in this group. 'any' is an OR include group. 'none' is an exclusion group equivalent to NOT (A OR B OR C)."
        ),
    ]
    signals: Annotated[
        list[package_signal_targeting.PackageSignalTargeting],
        Field(
            description='Signal targeting entries evaluated by this group. Each entry uses the package signal targeting shape, including signal_ref, value expression, and optional pricing, execution-handle, or activation fields.',
            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 model_config
var operator : Operator
var signals : list[PackageSignalTargeting5 | PackageSignalTargeting6 | PackageSignalTargeting7]

Inherited members

class PackageSignalTargetingGroups (**data: Any)
Expand source code
class PackageSignalTargetingGroups(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    operator: Annotated[
        Literal['all'],
        Field(
            description="Groups-level operator. Required even though v1 only supports 'all': every child group must be satisfied."
        ),
    ] = 'all'
    groups: Annotated[
        list[package_signal_targeting_group.PackageSignalTargetingGroup],
        Field(
            description="Signal targeting groups to evaluate. Use operator 'any' for include groups and 'none' for exclusion groups.",
            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 groups : list[PackageSignalTargetingGroup]
var model_config
var operator : Literal['all']

Inherited members

class PackageTargetingResolution (**data: Any)
Expand source code
class PackageTargetingResolution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    demographics: Annotated[
        demographic_targeting_resolution.DemographicTargetingResolution,
        Field(
            description='Canonical demographic predicate and exact seller execution details. Include whenever demographic targeting was requested or applied.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 demographics : DemographicTargetingResolution
var ext : ExtensionObject | None
var model_config

Inherited members

class PaginationRequest (**data: Any)
Expand source code
class PaginationRequest(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    max_results: Annotated[
        SchemaInt | None,
        Field(description='Maximum number of items to return per page', ge=1, le=100),
    ] = 50
    cursor: Annotated[
        str | None,
        Field(description='Opaque cursor from a previous response to fetch the next page'),
    ] = 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 cursor : str | None
var max_results : int | None
var model_config

Inherited members

class PaginationResponse (**data: Any)
Expand source code
class PaginationResponse(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    has_more: Annotated[
        StrictBool, Field(description='Whether more results are available beyond this page')
    ]
    cursor: Annotated[
        str | None,
        Field(
            description='Opaque cursor to pass in the next request to fetch the next page. Only present when has_more is true.'
        ),
    ] = None
    total_count: Annotated[
        SchemaInt | None,
        Field(
            description='Total number of items matching the query across all pages. Optional because not all backends can efficiently compute this.',
            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

Class variables

var cursor : str | None
var has_more : bool
var model_config
var total_count : int | None

Inherited members

class Panel (**data: Any)
Expand source code
class Panel(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    identifiers: Annotated[
        list[Identifier],
        Field(description='All identifiers for this panel, one entry per scheme', min_length=1),
    ]
    name: Annotated[
        str | None,
        Field(
            description="Human-readable location description (e.g., 'I-95 N of Exit 12, right-hand read')"
        ),
    ] = 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 identifiers : list[Identifier]
var model_config
var name : str | None

Inherited members

class ParentLabel (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ParentLabel(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str

Subclasses

class Path (*args, **kwds)
Expand source code
class Path(StrEnum):
    field_geo_countries = '/geo_countries'
    field_geo_countries_exclude = '/geo_countries_exclude'
    field_geo_regions = '/geo_regions'
    field_geo_regions_exclude = '/geo_regions_exclude'
    field_geo_postal_areas = '/geo_postal_areas'
    field_geo_postal_areas_exclude = '/geo_postal_areas_exclude'
    field_audience_include = '/audience_include'
    field_audience_exclude = '/audience_exclude'
    field_device_platform = '/device_platform'
    field_device_platform_exclude = '/device_platform_exclude'
    field_device_type = '/device_type'
    field_device_type_exclude = '/device_type_exclude'
    field_browser = '/browser'
    field_browser_exclude = '/browser_exclude'
    field_language = '/language'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var field_audience_exclude
var field_audience_include
var field_browser
var field_browser_exclude
var field_device_platform
var field_device_platform_exclude
var field_device_type
var field_device_type_exclude
var field_geo_countries
var field_geo_countries_exclude
var field_geo_postal_areas
var field_geo_postal_areas_exclude
var field_geo_regions
var field_geo_regions_exclude
var field_language
class Payload1 (**data: Any)
Expand source code
class Payload1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    property_rid: UUID
    last_resolved_at: AwareDatetime | None = None
    reason: str | 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 last_resolved_at : pydantic.types.AwareDatetime | None
var model_config
var property_rid : uuid.UUID
var reason : str | None

Inherited members

class Payload10 (**data: Any)
Expand source code
class Payload10(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Domain | None = None
    domain: Annotated[
        Domain | None,
        Field(
            deprecated=True,
            description='Legacy alias for publisher_domain retained for early feed examples.',
        ),
    ] = None
    properties_added: Annotated[SchemaInt | None, Field(ge=0)] = None
    properties_removed: Annotated[SchemaInt | None, Field(ge=0)] = None
    agents_added: list[AnyUrl] | None = None
    agents_removed: list[AnyUrl] | None = None
    agent_count: Annotated[SchemaInt | None, Field(ge=0)] = None
    property_count: Annotated[SchemaInt | None, Field(ge=0)] = None
    collection_count: Annotated[SchemaInt | None, Field(ge=0)] = None
    format_count: Annotated[
        SchemaInt | None,
        Field(description='Number of top-level formats[] declarations after this revision.', ge=0),
    ] = None
    placement_count: Annotated[
        SchemaInt | None,
        Field(
            description='Number of top-level placements[] declarations after this revision.', ge=0
        ),
    ] = None
    changed_fields: ChangedFields | None = None
    discovery_method: str | None = None
    manager_domain: str | None = None
    source: str | 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

Subclasses

Class variables

var agent_count : int | None
var agents_added : list[pydantic.networks.AnyUrl] | None
var agents_removed : list[pydantic.networks.AnyUrl] | None
var changed_fields : ChangedFields | None
var collection_count : int | None
var discovery_method : str | None
var domain : Domain | None
var format_count : int | None
var manager_domain : str | None
var model_config
var placement_count : int | None
var properties_added : int | None
var properties_removed : int | None
var property_count : int | None
var publisher_domain : Domain | None
var source : str | None

Inherited members

class Payload11 (**data: Any)
Expand source code
class Payload11(PublisherAdagentsPayload):
    properties_added: Annotated[SchemaInt | None, Field(ge=0)] = None
    properties_removed: Annotated[SchemaInt | None, Field(ge=0)] = None
    agents_added: list[AnyUrl] | None = None
    agents_removed: list[AnyUrl] | None = None
    changed_fields: ChangedFields | 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 agents_added : list[pydantic.networks.AnyUrl] | None
var agents_removed : list[pydantic.networks.AnyUrl] | None
var changed_fields : ChangedFields | None
var model_config
var properties_added : int | None
var properties_removed : int | None

Inherited members

class Payload12 (**data: Any)
Expand source code
class Payload12(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    id: Annotated[
        UUID | None,
        Field(
            description='Registry authorization row id when the event is backed by a materialized effective authorization row.'
        ),
    ] = None
    agent_url: AnyUrl
    agent_url_canonical: Annotated[
        str | None,
        Field(description='Registry-canonicalized form of agent_url for equality checks.'),
    ] = None
    publisher_domain: Domain
    authorization_type: Annotated[
        AuthorizationType | None,
        Field(
            description='When present, identifies the adagents.json authorization variant represented by this payload.'
        ),
    ] = None
    authorized_for: str | None = None
    property_ids: Annotated[list[property_id.PropertyId] | None, Field(min_length=1)] = None
    property_tags: Annotated[list[property_tag.PropertyTag] | None, Field(min_length=1)] = None
    properties: Annotated[list[property_1.Property] | None, Field(min_length=1)] = None
    publisher_properties: Annotated[
        list[publisher_property_selector.PublisherPropertySelector] | None, Field(min_length=1)
    ] = None
    property_rid: Annotated[
        UUID | None,
        Field(
            description='Catalog property_rid for materialized per-property authorization rows. Null for publisher-wide rows.'
        ),
    ] = None
    property_id_slug: Annotated[
        str | None,
        Field(
            description='Publisher-local property id for materialized per-property authorization rows.'
        ),
    ] = None
    placement_ids: Annotated[list[str] | None, Field(min_length=1)] = None
    placement_tags: Annotated[list[str] | None, Field(min_length=1)] = None
    collections: Annotated[
        list[collection_selector.CollectionSelector] | None,
        Field(
            description='Collection constraints from authorized_agents[*].collections. When set, the event does NOT authorize the property unqualified — consumers building a local authorization index MUST scope the grant to these selectors and fail closed when a query carries no collection scope. A selector without collection_ids is a bulk grant for all collections declared at that publisher_domain.',
            min_length=1,
        ),
    ] = None
    countries: Countries | None = None
    delegation_type: DelegationType | None = None
    exclusive: StrictBool | None = None
    signing_keys: Annotated[
        list[agent_signing_key.AgentSigningKey] | None,
        Field(
            description='Publisher-attested signing keys copied from adagents.json when the registry has them. Advisory in feed events; verifiers MUST re-fetch the authoritative publisher artifact before treating keys as a trust anchor.',
            min_length=1,
        ),
    ] = None
    effective_from: AwareDatetime | None = None
    effective_until: AwareDatetime | None = None
    evidence: Evidence | None = None
    disputed: StrictBool | None = None
    created_by: str | None = None
    expires_at: AwareDatetime | None = None
    created_at: AwareDatetime | None = None
    updated_at: AwareDatetime | None = None
    override_applied: StrictBool | None = None
    override_reason: str | 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

Subclasses

Class variables

var agent_url : pydantic.networks.AnyUrl
var agent_url_canonical : str | None
var authorization_type : AuthorizationType | None
var authorized_for : str | None
var collections : list[CollectionSelector] | None
var countries : Countries | None
var created_at : pydantic.types.AwareDatetime | None
var created_by : str | None
var delegation_type : DelegationType | None
var disputed : bool | None
var effective_from : pydantic.types.AwareDatetime | None
var effective_until : pydantic.types.AwareDatetime | None
var evidence : Evidence | None
var exclusive : bool | None
var expires_at : pydantic.types.AwareDatetime | None
var id : uuid.UUID | None
var model_config
var override_applied : bool | None
var override_reason : str | None
var placement_ids : list[str] | None
var placement_tags : list[str] | None
var properties : list[Property] | None
var property_id_slug : str | None
var property_ids : list[PropertyId] | None
var property_rid : uuid.UUID | None
var property_tags : list[PropertyTag] | None
var publisher_domain : Domain
var publisher_properties : list[PublisherPropertySelector1 | PublisherPropertySelector2 | PublisherPropertySelector3] | None
var signing_keys : list[AgentSigningKey] | None
var updated_at : pydantic.types.AwareDatetime | None

Inherited members

class Payload13 (**data: Any)
Expand source code
class Payload13(Payload12):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Payload14 (**data: Any)
Expand source code
class Payload14(Payload12):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Payload17 (**data: Any)
Expand source code
class Payload17(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: str
    product: Annotated[
        product_1.Product | None,
        Field(
            description='Legacy 3.x post-change Product. Subscribers using get_products consume this form.'
        ),
    ] = None
    canonical_product: Annotated[
        canonical_product_1.CanonicalProduct | None,
        Field(
            description='Canonical post-change Product for subscribers that negotiated lifecycle_tools.list_products. Consumers replace the matching canonical mirror entry directly.'
        ),
    ] = None
    applies_to: Annotated[
        AppliesTo,
        Field(
            description="REQUIRED. Sellers MUST declare the cache layer explicitly on every *.created event. When introducing an entity that exists only in an account overlay (e.g., a custom product for a single account), the seller MUST emit { scope: 'account', account_ids: [...] } to prevent the entity from leaking into every consumer's public-layer cache. For public-layer additions, declare { scope: 'public' } explicitly rather than relying on a default — schema-required declaration prevents the quiet-failure path where a forgotten applies_to leaks an account-only entity to all consumers."
        ),
    ]

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 applies_to : AppliesTo1 | AppliesTo2
var canonical_product : CanonicalProduct | None
var model_config
var product : Product | None
var product_id : str

Inherited members

class Payload18 (**data: Any)
Expand source code
class Payload18(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: str
    product: Annotated[
        product_1.Product | None,
        Field(description='Legacy 3.x post-change Product for get_products mirrors.'),
    ] = None
    canonical_product: Annotated[
        canonical_product_1.CanonicalProduct | None,
        Field(description='Canonical post-change Product for list_products mirrors.'),
    ] = None
    changed_fields: Annotated[
        list[str] | None,
        Field(
            description="Advisory list of changed top-level field names (e.g., ['format_ids', 'performance_standards']). Consumers MAY use for fine-grained re-render, but the product object is the source of truth for this webhook payload."
        ),
    ] = None
    applies_to: AppliesTo

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 applies_to : AppliesTo1 | AppliesTo2
var canonical_product : CanonicalProduct | None
var changed_fields : list[str] | None
var model_config
var product : Product | None
var product_id : str

Inherited members

class Payload2 (**data: Any)
Expand source code
class Payload2(PropertyPayload):
    reactivated_at: AwareDatetime | None = None
    property_rid: Any

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var property_rid : Any
var reactivated_at : pydantic.types.AwareDatetime | None

Inherited members

class Payload20 (**data: Any)
Expand source code
class Payload20(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: str
    removal_reason: RemovalReason | None = None
    applies_to: AppliesTo

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 applies_to : AppliesTo1 | AppliesTo2
var model_config
var product_id : str
var removal_reason : RemovalReason | None

Inherited members

class Payload21 (**data: Any)
Expand source code
class Payload21(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_agent_segment_id: str
    signal_ref: signal_ref_1.SignalRef | None = None
    applies_to: Annotated[
        AppliesTo,
        Field(
            description="REQUIRED. Agents MUST declare the cache layer explicitly on every *.created event. When introducing a signal that exists only in an account overlay (e.g., a custom segment for a single account), the agent MUST emit { scope: 'account', account_ids: [...] } to prevent leak into every consumer's public-layer cache. For public-layer additions, declare { scope: 'public' } explicitly rather than relying on a default — schema-required declaration prevents the quiet-failure path."
        ),
    ]
    signal: Annotated[Signal, Field(description='Full post-change signal object.')]

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 applies_to : AppliesTo1 | AppliesTo2
var model_config
var signal : Signal
var signal_agent_segment_id : str
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None

Inherited members

class Payload22 (**data: Any)
Expand source code
class Payload22(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_agent_segment_id: str
    signal_ref: signal_ref_1.SignalRef | None = None
    changed_fields: Annotated[
        list[str] | None,
        Field(
            description='Advisory list of changed top-level field names. Consumers MAY use for fine-grained re-render, but the signal object is the source of truth for this webhook payload.'
        ),
    ] = None
    applies_to: AppliesTo
    signal: Annotated[
        Signal,
        Field(
            description='Full post-change signal object. Consumers replace the prior signal mirror entry with this object.'
        ),
    ]

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 applies_to : AppliesTo1 | AppliesTo2
var changed_fields : list[str] | None
var model_config
var signal : Signal
var signal_agent_segment_id : str
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None

Inherited members

class Payload23 (**data: Any)
Expand source code
class Payload23(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_agent_segment_id: str
    signal_ref: signal_ref_1.SignalRef | None = None
    pricing_options: Annotated[
        list[vendor_pricing_option.VendorPricingOption],
        Field(description='Full post-change pricing_options array. NOT a delta.', min_length=1),
    ]
    previous_pricing_option_ids: list[str] | None = None
    effective_at: Annotated[
        AwareDatetime | None,
        Field(
            description='When the price change takes effect. A value in the future is a pre-announcement: consumers MAY warm caches but MUST NOT bind decisions until the effective time has passed. See specs/wholesale-feed-webhooks.md §`effective_at` and pre-announce.'
        ),
    ] = None
    retracts_event_id: Annotated[
        UUID | None,
        Field(
            description='Optional. When this event retracts a prior pre-announced *.priced, set this to the event_id of the announcement being retracted. See product.priced for the full retraction contract.'
        ),
    ] = None
    applies_to: AppliesTo

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 applies_to : AppliesTo1 | AppliesTo2
var effective_at : pydantic.types.AwareDatetime | None
var model_config
var previous_pricing_option_ids : list[str] | None
var pricing_options : list[VendorPricingOption7 | VendorPricingOption8 | VendorPricingOption9 | VendorPricingOption10 | VendorPricingOption11]
var retracts_event_id : uuid.UUID | None
var signal_agent_segment_id : str
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None

Inherited members

class Payload24 (**data: Any)
Expand source code
class Payload24(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_agent_segment_id: str
    signal_ref: signal_ref_1.SignalRef | None = None
    removal_reason: RemovalReason | None = None
    applies_to: AppliesTo

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 applies_to : AppliesTo1 | AppliesTo2
var model_config
var removal_reason : RemovalReason | None
var signal_agent_segment_id : str
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None

Inherited members

class Payload25 (**data: Any)
Expand source code
class Payload25(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    summary: Annotated[
        str,
        Field(
            description="Human-readable description of the bulk operation (e.g., 'Q3 2026 rate card refresh')."
        ),
    ]
    affected_count: Annotated[
        SchemaInt, Field(description='Approximate count of affected entities.', ge=1)
    ]
    recommendation: Annotated[
        Literal['wholesale_resync'] | None,
        Field(
            description='Advisory recommendation. Consumers SHOULD repair by re-reading the affected feed named by affected_entity_type; the recommendation is not a synchronized trigger. Modeled as a single-value enum (not a boolean) so future minor versions can extend the recommendation vocabulary without a breaking shape change. Consumers MUST be prepared to ignore unknown recommendation values.'
        ),
    ] = None
    applies_to: AppliesTo
    affected_entity_type: Annotated[
        AffectedEntityType,
        Field(
            description='Which wholesale feed this bulk operation touched. A bulk operation that changes both products and signals MUST emit one webhook per feed so each envelope carries the correct post-change wholesale_feed_version.'
        ),
    ]

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 affected_count : int
var affected_entity_type : AffectedEntityType
var applies_to : AppliesTo1 | AppliesTo2
var model_config
var recommendation : Literal['wholesale_resync'] | None
var summary : str

Inherited members

class Payload3 (**data: Any)
Expand source code
class Payload3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    alias_rid: Annotated[
        UUID, Field(description='Retired collection_rid that now aliases to canonical_rid.')
    ]
    canonical_rid: Annotated[
        UUID, Field(description='Canonical collection_rid that consumers should retain.')
    ]
    evidence: Annotated[
        str | None,
        Field(
            description='Registry evidence source for the merge, such as adagents_json or manual_review.'
        ),
    ] = 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 alias_rid : uuid.UUID
var canonical_rid : uuid.UUID
var evidence : str | None
var model_config

Inherited members

class Payload4 (**data: Any)
Expand source code
class Payload4(CollectionPayload):
    status: Literal['removed'] = 'removed'  # type: ignore[assignment]
    collection_rid: Any
    publisher_domain: Any

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 collection_rid : Any
var model_config
var publisher_domain : Any
var status : Literal['removed']

Inherited members

class Payload5 (**data: Any)
Expand source code
class Payload5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    agent_url: AnyUrl
    removed_from_publishers: Annotated[list[Domain] | None, Field(min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var model_config
var removed_from_publishers : list[Domain] | None

Inherited members

class Payload6 (**data: Any)
Expand source code
class Payload6(AgentProfilePayload):
    changed_fields: ChangedFields | None = None
    agent_url: Any

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : Any
var changed_fields : ChangedFields | None
var model_config

Inherited members

class Payload7 (**data: Any)
Expand source code
class Payload7(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    agent_url: AnyUrl
    previous_status: ComplianceStatus
    current_status: ComplianceStatus
    headline: str | None = None
    tracks: Annotated[
        dict[str, Tracks], Field(description='Map of compliance track id to track status.')
    ]
    storyboards_passing: Annotated[SchemaInt, Field(ge=0)]
    storyboards_total: Annotated[SchemaInt, Field(ge=0)]
    storyboards: list[Storyboard] | 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

Subclasses

Class variables

var agent_url : pydantic.networks.AnyUrl
var current_status : ComplianceStatus
var headline : str | None
var model_config
var previous_status : ComplianceStatus
var storyboards : list[Storyboard] | None
var storyboards_passing : int
var storyboards_total : int
var tracks : dict[str, Tracks]

Inherited members

class Payload8 (**data: Any)
Expand source code
class Payload8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    agent_url: AnyUrl
    role: BadgeRole
    verified_specialisms: Annotated[list[str], Field(min_length=1)]
    adcp_version: str | None = None
    grading_profile: Annotated[
        GradingProfile | None,
        Field(
            description='Grading profile that produced the badge. Historical events emitted before profile selection may omit this field and are Legacy.'
        ),
    ] = 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 adcp_version : str | None
var agent_url : pydantic.networks.AnyUrl
var grading_profile : GradingProfile | None
var model_config
var role : BadgeRole
var verified_specialisms : list[str]

Inherited members

class Payload9 (**data: Any)
Expand source code
class Payload9(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    agent_url: AnyUrl
    role: BadgeRole
    reason: str
    adcp_version: str | None = None
    grading_profile: Annotated[
        GradingProfile | None,
        Field(
            description='Grading profile in force when the badge was lost. Historical events emitted before profile selection may omit this field and are Legacy.'
        ),
    ] = 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 adcp_version : str | None
var agent_url : pydantic.networks.AnyUrl
var grading_profile : GradingProfile | None
var model_config
var reason : str
var role : BadgeRole

Inherited members

class PaymentTerms (*args, **kwds)
Expand source code
class PaymentTerms(StrEnum):
    net_30 = 'net_30'
    net_60 = 'net_60'
    net_90 = 'net_90'
    prepaid = 'prepaid'
    due_on_receipt = 'due_on_receipt'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var due_on_receipt
var net_30
var net_60
var net_90
var prepaid
class PerformanceFeedback (**data: Any)
Expand source code
class PerformanceFeedback(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    feedback_id: Annotated[
        str, Field(description='Unique identifier for this performance feedback submission')
    ]
    media_buy_id: Annotated[str, Field(description="Publisher's media buy identifier")]
    package_id: Annotated[
        str | None,
        Field(
            description='Specific package within the media buy (if feedback is package-specific)'
        ),
    ] = None
    creative_id: Annotated[
        str | None, Field(description='Specific creative asset (if feedback is creative-specific)')
    ] = None
    measurement_period: Annotated[
        MeasurementPeriod, Field(description='Time period for performance measurement')
    ]
    performance_index: Annotated[
        StrictFloat,
        Field(
            description='Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)',
            ge=0.0,
        ),
    ]
    metric_type: Annotated[
        metric_type_1.MetricType | None,
        Field(
            deprecated=True,
            description='**Deprecated as of this minor.** The legacy free-form metric enum that mixes metrics, verification, and attribution into one list. New implementations SHOULD use `metric` (the discriminated `(scope, metric_id, qualifier)` row shape) and populate `metric_type` with a best-effort string for one-minor backwards compatibility. When both `metric` and `metric_type` are present, consumers MUST use `metric` for dispatch. Removed at the next major. See [docs/measurement/taxonomy](https://docs.adcontextprotocol.org/docs/measurement/taxonomy) for why the layered shape replaces the flat enum.',
        ),
    ] = None
    metric: Annotated[
        Metric | Metric7 | None,
        Field(
            description='The metric this feedback row pertains to, using the same `(scope, metric_id, qualifier)` row shape as `committed_metrics` and package-level delivery values (`metric_values` or `vendor_metric_values`). Preferred over the legacy `metric_type` field for new implementations. Brings performance-feedback into the same atomic unit and dispatch model as the rest of the measurement surface — buyer agents reconcile feedback against the contract surface using the row-level join on `(scope, metric_id, qualifier)`. **Optional and may be omitted entirely for holistic feedback** (e.g., a trader flagging a campaign as underperforming without a specific metric in mind — `performance_index` plus the response narrative carry the signal). Senders SHOULD populate `metric` when the feedback is metric-specific so consumers can route it to the right optimization path; senders MAY omit it for general performance feedback.',
            discriminator='scope',
        ),
    ] = None
    feedback_source: Annotated[
        feedback_source_1.FeedbackSource, Field(description='Source of the performance data')
    ]
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description="Vendor that produced this feedback. SHOULD be populated when `feedback_source` is `third_party_measurement` or `verification_partner` AND a single attesting vendor exists — without it, the row is unattributed and consumers can't verify authorization, resolve metric definitions, or route disputes. OMIT for blended outputs where no single vendor owns the result: MMM mixes (Nielsen MMM, Analytic Partners, in-house mix models combining multiple vendor inputs), multi-touch attribution outputs that join across vendors, and clean-room outputs (LiveRamp, Habu, AWS Clean Rooms) where the clean room is not the measurement source. For these cases, leave `vendor` absent and use the response's narrative payload to describe provenance. Optional for `buyer_attribution` and `platform_analytics` (those sources are implicit from context). The vendor's `brand.json` `agents[type='measurement']` is the discovery anchor; metric definitions live on the agent's `get_adcp_capabilities.measurement.metrics[]` block. Same identity discipline as `vendor_metric_value.vendor` and `performance-standard.vendor`."
        ),
    ] = None
    status: Annotated[Status, Field(description='Processing status of the performance feedback')]
    submitted_at: Annotated[
        AwareDatetime, Field(description='ISO 8601 timestamp when feedback was submitted')
    ]
    applied_at: Annotated[
        AwareDatetime | None,
        Field(
            description='ISO 8601 timestamp when feedback was applied to optimization algorithms'
        ),
    ] = 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 applied_at : pydantic.types.AwareDatetime | None
var creative_id : str | None
var feedback_id : str
var feedback_source : FeedbackSource
var measurement_period : MeasurementPeriod
var media_buy_id : str
var metric : Metric | Metric7 | None
var metric_type : MetricType | None
var model_config
var package_id : str | None
var performance_index : float
var status : Status
var submitted_at : pydantic.types.AwareDatetime
var vendor : BrandReference | None

Inherited members

class PerformanceFeedbackAssertion (**data: Any)
Expand source code
class PerformanceFeedbackAssertion(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    media_buy_id: Annotated[
        str,
        Field(
            description="Receiver-scoped media buy identifier. On the provider-to-orchestrator hop this is the orchestrator's measurement-facing identifier; on the orchestrator-to-seller hop it is the seller-assigned media buy identifier.",
            min_length=1,
        ),
    ]
    package_id: Annotated[
        str | None,
        Field(
            description='Receiver-scoped package identifier when the assertion is package-specific. The orchestrator maps its measurement-facing identifier to seller-local identifiers during fan-out.',
            min_length=1,
        ),
    ] = None
    creative_id: Annotated[
        str | None,
        Field(
            description='Receiver-scoped creative identifier when the assertion is creative-specific. The orchestrator maps its measurement-facing identifier to seller-local identifiers during fan-out.',
            min_length=1,
        ),
    ] = None
    measurement_period: Annotated[
        datetime_range.DatetimeRange,
        Field(description='Period whose performance is summarized by this assertion.'),
    ]
    performance_index: Annotated[
        StrictFloat,
        Field(
            description='Normalized decision signal where 1.0 equals the named baseline, values below 1.0 underperform it, and values above 1.0 outperform it. Compact-contract producers (baseline present) MUST use observed divided by baseline for higher-is-better ratio metrics and baseline divided by observed for lower-is-better ratio metrics such as cost per acquisition.',
            ge=0.0,
        ),
    ]
    baseline: Annotated[
        performance_baseline.PerformanceBaseline | None,
        Field(
            description='Expectation represented by performance_index = 1.0. Compact-contract producers MUST populate this field; it remains optional in the schema so existing 3.x request payloads remain valid.'
        ),
    ] = None
    metric: Annotated[
        performance_feedback_metric.PerformanceFeedbackMetric | None,
        Field(
            description='Metric this assertion describes. Omit only for holistic feedback that is not attributable to one metric.'
        ),
    ] = None
    metric_type: Annotated[
        metric_type_1.MetricType | None,
        Field(
            deprecated=True,
            description='Deprecated legacy metric classification retained for existing request payloads. New implementations SHOULD use metric; when both are present consumers MUST use metric for dispatch.',
        ),
    ] = None
    producer: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description='Brand that produced the analysis. The receiving orchestrator gateway verifies this reference against authenticated caller identity and preserves it during seller fan-out.'
        ),
    ] = None
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(
            deprecated=True,
            description='Deprecated alias for producer retained for previously documented request payloads. When both are present consumers use producer.',
        ),
    ] = None
    feedback_source: Annotated[
        feedback_source_1.FeedbackSource | None,
        Field(description='Legacy categorical source hint retained for existing request payloads.'),
    ] = None
    methodology: Annotated[
        str | None,
        Field(
            description='Producer-scoped methodology identifier such as geo_incrementality, media_mix_model, or deterministic_attribution.',
            max_length=100,
            min_length=1,
        ),
    ] = None
    methodology_version: Annotated[
        str | None,
        Field(
            description='Producer-defined version of the methodology used for this assertion.',
            max_length=100,
            min_length=1,
        ),
    ] = None
    study_ref: Annotated[
        str | None,
        Field(
            description='Opaque producer-assigned study or model-run reference. Receivers use it for correlation only and MUST NOT interpret it as an experiment-execution instruction.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    evidence: Annotated[
        Evidence | None,
        Field(
            description='Small inline evidence summary used to weight the assertion without transporting the full study.'
        ),
    ] = None
    evidence_ref: Annotated[
        AnyUrl | None,
        Field(
            description='Provider-hosted evidence or result reference for parties authorized to inspect the full study.'
        ),
    ] = None
    as_of: Annotated[
        AwareDatetime | None, Field(description='When the producer computed this assertion.')
    ] = None
    final: Annotated[
        StrictBool | None,
        Field(
            description='Whether the producer expects this assertion to be revised as data matures.'
        ),
    ] = None
    supersedes_feedback_id: Annotated[
        str | None,
        Field(
            description='Receiver-issued feedback_id of the earlier assertion this one replaces at the same hop.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var as_of : pydantic.types.AwareDatetime | None
var baseline : PerformanceBaseline | None
var creative_id : str | None
var evidence : Evidence | None
var evidence_ref : pydantic.networks.AnyUrl | None
var feedback_source : FeedbackSource | None
var final : bool | None
var measurement_period : DatetimeRange
var media_buy_id : str
var methodology : str | None
var methodology_version : str | None
var metric : PerformanceFeedbackMetric1 | PerformanceFeedbackMetric2 | None
var metric_type : MetricType | None
var model_config
var package_id : str | None
var performance_index : float
var producer : BrandReference | None
var study_ref : str | None
var supersedes_feedback_id : str | None
var vendor : BrandReference | None

Inherited members

class PerformanceFeedbackMetric1 (**data: Any)
Expand source code
class PerformanceFeedbackMetric1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['standard'] = 'standard'
    metric_id: available_metric.AvailableMetric
    qualifier: Annotated[
        Qualifier | None,
        Field(
            description='Identity-affecting metric qualifiers. Statistical evidence and feedback-producer identity do not belong here.'
        ),
    ] = 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 metric_id : AvailableMetric
var model_config
var qualifier : Qualifier | None
var scope : Literal['standard']

Inherited members

class PerformanceFeedbackMetric2 (**data: Any)
Expand source code
class PerformanceFeedbackMetric2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Literal['vendor'] = 'vendor'
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description='Vendor that defines this metric. This can differ from the producer of the feedback assertion.'
        ),
    ]
    metric_id: vendor_metric_id.VendorMetricId
    qualifier: Annotated[
        Qualifier | None,
        Field(
            description='Optional disambiguator mirroring the vendor-scope qualifier on `committed_metrics` — same closed key set as standard-scope entries.'
        ),
    ] = 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 metric_id : VendorMetricId
var model_config
var qualifier : Qualifier | None
var scope : Literal['vendor']
var vendor : BrandReference

Inherited members

class PerformanceStandard (**data: Any)
Expand source code
class PerformanceStandard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    metric: Annotated[
        performance_standard_metric.PerformanceStandardMetric,
        Field(description='The performance metric this standard applies to.'),
    ]
    threshold: Annotated[
        StrictFloat,
        Field(
            description='Rate threshold as a decimal (e.g., 0.70 for 70%). Whether this is a floor or ceiling depends on the metric: for viewability, completion_rate, brand_safety, attention_score the actual rate must be >= threshold; for ivt the actual rate must be <= threshold.',
            ge=0.0,
            le=1.0,
        ),
    ]
    standard: Annotated[
        viewability_standard.ViewabilityStandard | None,
        Field(
            description="Measurement standard. Required when metric is 'viewability' (MRC and GroupM define materially different thresholds). Omit for other metrics."
        ),
    ] = None
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description="Vendor measuring this metric (e.g., { domain: 'doubleverify.com' }). The vendor's brand.json agents array (type: 'measurement') is the discovery point for their measurement agent. When specified on a confirmed package, creatives MUST include tracker_script or tracker_pixel assets from this vendor."
        ),
    ]

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 metric : PerformanceStandardMetric
var model_config
var standard : ViewabilityStandard | None
var threshold : float
var vendor : BrandReference

Inherited members

class PeriodAnchorPolicy (*args, **kwds)
Expand source code
class PeriodAnchorPolicy(StrEnum):
    fixed = 'fixed'
    configurable = 'configurable'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var configurable
var fixed
class PeriodTimezonePolicy (*args, **kwds)
Expand source code
class PeriodTimezonePolicy(StrEnum):
    fixed = 'fixed'
    account_resolved = 'account_resolved'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var account_resolved
var fixed
class Phase (*args, **kwds)
Expand source code
class Phase(StrEnum):
    exploratory = 'exploratory'
    planning = 'planning'
    active_sourcing = 'active_sourcing'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var active_sourcing
var exploratory
var planning
class PhysicalChecksums (**data: Any)
Expand source code
class PhysicalChecksums(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    object_ref: reporting_file_object_ref.ReportingFileObjectReference
    algorithm: Literal['sha256'] = 'sha256'
    value: Annotated[str, Field(pattern='^[A-Fa-f0-9]{64}$')]

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 algorithm : Literal['sha256']
var model_config
var object_ref : ReportingFileObjectReference
var value : str

Inherited members

class PhysicalChecksums1 (**data: Any)
Expand source code
class PhysicalChecksums1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    object_ref: reporting_file_object_ref.ReportingFileObjectReference
    algorithm: Literal['sha512'] = 'sha512'
    value: Annotated[str, Field(pattern='^[A-Fa-f0-9]{128}$')]

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 algorithm : Literal['sha512']
var model_config
var object_ref : ReportingFileObjectReference
var value : str

Inherited members

class PixelRatio (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class PixelRatio(ScalarFloat):
    __slots__ = ()
    _constraints = {'gt': 0.0}

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._scalar.ScalarFloat
  • adcp.types._scalar._ScalarRoot
  • builtins.float
class PixelTrackingEvent (*args, **kwds)
Expand source code
class PixelTrackingEvent(StrEnum):
    impression = 'impression'
    viewable_mrc_50 = 'viewable_mrc_50'
    viewable_mrc_100 = 'viewable_mrc_100'
    viewable_video_50 = 'viewable_video_50'
    audible_video_complete = 'audible_video_complete'
    click = 'click'
    custom = 'custom'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var audible_video_complete
var click
var custom
var impression
var viewable_mrc_100
var viewable_mrc_50
var viewable_video_50
class PlaceCatalogSupport (**data: Any)
Expand source code
class PlaceCatalogSupport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    countries: Annotated[
        dict[Annotated[str, StringConstraints(pattern=r'^[A-Z]{2}$')], list[geo_place_type.GeographicPlaceType]],
        Field(min_length=1),
    ]
    current_version: Annotated[
        str,
        Field(
            description='Version applied when a later package overlay omits system_version. Must be present in system_versions.',
            min_length=1,
        ),
    ]
    system_versions: Annotated[
        list[SystemVersion],
        Field(
            description='Exact catalog versions selectable on later package overlays.', min_length=1
        ),
    ]
    ext: ext_1.ExtensionObject | 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 countries : dict[str, list[GeographicPlaceType1 | GeographicPlaceType2]]
var current_version : str
var ext : ExtensionObject | None
var model_config
var system_versions : list[SystemVersion]

Inherited members

class PlaceSupport (**data: Any)
Expand source code
class PlaceSupport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    systems: Annotated[
        dict[geo_place_system.GeographicPlaceIdentifierSystem, PlaceCatalogSupport],
        Field(min_length=1),
    ]
    max_values_per_package: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_packages: Annotated[
        SchemaInt | None,
        Field(
            description='Optional maximum number of independently place-targeted packages the seller will create from this configured product.',
            ge=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var max_packages : int | None
var max_values_per_package : int | None
var model_config
var systems : dict[GeographicPlaceIdentifierSystem1 | GeographicPlaceIdentifierSystem2, PlaceCatalogSupport]

Inherited members

class Placement (**data: Any)
Expand source code
class Placement(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Annotated[
        Kind,
        Field(
            description='Placement authority discriminator. `publisher_ref` is publisher-catalog identity; `seller_inline` is sales-agent-authored identity.'
        ),
    ]
    placement_id: Annotated[
        str,
        Field(
            description='Placement identifier. For publisher_ref it is scoped by publisher_domain and resolves in adagents.json. For seller_inline it is scoped by seller_agent, or by the enclosing seller and product for legacy rows.'
        ),
    ]
    publisher_domain: Annotated[
        str | None,
        Field(
            description="For publisher_ref, the domain whose adagents.json declares the placement and part of canonical identity. For seller_inline, optional inventory-publisher attribution only; it does not grant the seller authority to mint IDs in that publisher's catalog namespace.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    seller_agent: Annotated[
        seller_agent_ref.SellerAgentReference | None,
        Field(
            description='Sales agent that defines a seller_inline placement. Together with placement_id this is its self-contained identity. New 3.2 sellers SHOULD populate it; legacy product-context inline placements may omit it. Not used for publisher_ref.'
        ),
    ] = None
    name: Annotated[
        str | None,
        Field(
            description='Human-readable name for the placement (e.g., \'Homepage Banner\', \'Article Sidebar\'). Required for `kind: "seller_inline"`. May be omitted for publisher-referenced placements because buyers resolve the name from the publisher declaration identified by `{publisher_domain, placement_id}`.'
        ),
    ] = None
    description: Annotated[
        str | None, Field(description='Detailed description of where and how the placement appears')
    ] = None
    mode: Annotated[
        Mode,
        Field(
            description="Required product-level relationship to this placement. targetable means the buyer may include the publisher-scoped ref in targeting_overlay.placement_selection; a creative may be routed there only after it is purchased. included means fixed product inventory: it cannot be independently selected, but across discovery, create, and update a selected request exactly equal to the product's complete included placement set is an inherent restatement and may be echoed on the package without overlay_support.placement_selection. A product containing any included placement MUST NOT declare overlay_support.placement_selection; partial selection requires a separately selectable product configuration. During the migration window ending 2026-11-25, buyers MAY tolerate legacy products that omit mode and treat them as targetable; after that date buyers SHOULD fail closed."
        ),
    ]
    tags: Annotated[
        list[str] | None,
        Field(
            description="Optional tags for grouping placements within a product (e.g., 'homepage', 'native', 'premium'). When the placement_id comes from the publisher registry, these should align with the registry tags unless the product is narrowing scope."
        ),
    ] = None
    format_ids: Annotated[
        Sequence[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Legacy named-format placement narrowing. Can include concrete, template, or parameterized format IDs. When present on a product placement, this field narrows the product-level `format_ids` contract and MUST NOT introduce formats the product does not accept. Use canonical `format_options`.',
            min_length=1,
        ),
    ] = None
    format_options: Annotated[
        list[product_format_declaration.ProductFormatDeclaration] | None,
        Field(
            description="Canonical seller-side narrowing for this product placement. When present, these declarations are intersected with the product-level format_options and MUST NOT introduce a format outside that product upper bound. For kind publisher_ref, buyers MUST also resolve {publisher_domain, placement_id} in the publisher's adagents.json and intersect the publisher catalog constraint: use the public placement's format_options when present (resolving bare format_option_id references against same-file top-level formats[]), otherwise use applicable top-level formats[] scoped to that placement's properties. Omitting this inline field removes only the seller-inline layer; it does not bypass a publisher placement or property-scoped narrowing. The placement inherits the full product-level set only when no applicable publisher catalog narrowing exists. Unresolved publisher placement or format-option references fail closed. Locale policy participates in the same intersection: when the product policy is absent, a placement may introduce any concrete policy as a narrowing of the unconstrained option; when both are present, every placement accepted_language_range must be contained by a product range under RFC 4647 Basic Filtering (`fr-CA` narrows `fr`; `fr` does not narrow `fr-CA`). Buyers compute effective locale eligibility independently for each placement. Any effective locale-constrained route is canonical-only and has no projecting product or placement format_id.",
            min_length=1,
        ),
    ] = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None,
        Field(
            description='Declared video placement types for this product placement, using IAB Tech Lab/OpenRTB 2.6 video.plcmt definitions with AdCP-native names. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None,
        Field(
            description='Declared audio distribution types for this product placement, using IAB Tech Lab/OpenRTB 2.6 audio.feed definitions with AdCP-native names. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None,
        Field(
            description='Declared sponsored-placement types for this product placement, distinguishing where the catalog-driven retail-media placement renders on the retailer surface. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None,
        Field(
            description='Declared social-placement surfaces for this product placement, distinguishing the in-app surface where the social placement renders. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    identifiers: Annotated[
        list[Identifier] | None,
        Field(
            description='Optional external inventory identifiers for this placement, using the same {type, value} shape as property identifiers. Externally governed IDs should be authority-prefixed (e.g., space:1234931339, geopath:30961, fcc:73953). Seller-local IDs are opaque values scoped by the surrounding publisher namespace. Useful for DOOH venue and installed-endpoint IDs, broadcast facility IDs, and any channel where placements map to externally registered inventory. For kind: publisher_ref, the effective identifier set is the union of the resolved publisher declaration and this product declaration, de-duplicated by exact (type, value); a product cannot suppress a publisher-declared identifier by omission.',
            min_length=1,
        ),
    ] = None
    dooh_placement_attributes: ProductDoohPlacementAttributes | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> Placement:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('name',), ('publisher_domain',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'Placement requires at least one of these field groups: name | publisher_domain'
        )

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 audio_distribution_types : list[AudioDistributionType] | None
var description : str | None
var dooh_placement_attributes : ProductDoohPlacementAttributes | None
var format_ids : collections.abc.Sequence[FormatReferenceStructuredObject] | None
var format_options : list[ProductFormatDeclaration1 | ProductFormatDeclaration2 | ProductFormatDeclaration3 | ProductFormatDeclaration4 | ProductFormatDeclaration5 | ProductFormatDeclaration6 | ProductFormatDeclaration7 | ProductFormatDeclaration8 | ProductFormatDeclaration9 | ProductFormatDeclaration10 | ProductFormatDeclaration11 | ProductFormatDeclaration12 | ProductFormatDeclaration13 | ProductFormatDeclaration14 | ProductFormatDeclaration15 | ProductFormatDeclaration16] | None
var identifiers : list[Identifier] | None
var kind : Kind
var mode : Mode
var model_config
var name : str | None
var placement_id : str
var publisher_domain : str | None
var seller_agent : SellerAgentReference | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var tags : list[str] | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class PlacementDefinition (**data: Any)
Expand source code
class PlacementDefinition(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    placement_id: Annotated[
        str, Field(description='Stable placement identifier unique within this adagents.json file.')
    ]
    name: Annotated[
        str,
        Field(
            description="Human-readable placement name (e.g., 'Homepage Banner', 'Pre-roll', 'Sponsored Listing Slot 1')."
        ),
    ]
    description: Annotated[
        str | None, Field(description='Description of where and how this placement appears.')
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for grouping and querying placements across properties and products (e.g., 'homepage', 'native', 'premium', 'pre_roll')."
        ),
    ] = None
    property_ids: Annotated[
        list[property_id.PropertyId] | None,
        Field(
            description='Property IDs in this adagents.json where this placement can appear.',
            min_length=1,
        ),
    ] = None
    property_tags: Annotated[
        list[property_tag.PropertyTag] | None,
        Field(
            description="Property tags in this adagents.json where this placement can appear. Useful for network-wide positions such as 'pre_roll' or 'homepage_native_feed'.",
            min_length=1,
        ),
    ] = None
    collection_ids: Annotated[
        list[str] | None,
        Field(
            description='Optional collection IDs in this adagents.json where this placement is valid. Use to narrow a placement to specific content programs carried on the selected properties.',
            min_length=1,
        ),
    ] = None
    channels: Annotated[
        list[channels_1.MediaChannel] | None,
        Field(
            description='Advertising channels where this placement can run. Products that reference the placement may narrow this set but should not broaden it.',
            min_length=1,
        ),
    ] = None
    presentation_ref: Annotated[
        presentation_ref_1.PlacementPresentationReference | None,
        Field(
            description="Optional publisher-specific declarative frame for representing this placement's real chrome offline. It composes around the selected creative rendering unless the publisher-delegated preview_provider route explicitly covers placement presentation. It MUST NOT be promoted to or copied onto a shared format entry."
        ),
    ] = None
    preview_provider: Annotated[
        preview_provider_1.PublisherDesignatedPreviewProvider | None,
        Field(
            description="Optional publisher delegation to a callable AdCP preview provider for specific format options on this placement. This publisher-origin route is the only mechanism that grants preview authority inside the placement's scope; an agent's own rendering_origin description does not."
        ),
    ] = None
    format_options: Annotated[
        list[FormatOptions | product_format_declaration.ProductFormatDeclaration] | None,
        Field(
            description="Optional 3.1+ canonical format-option declarations supported by this placement. This `adagents.json` placement surface supports two entry shapes: (1) reference an entry in the same file's top-level `formats[]` by `format_option_id` only — buyers resolve the full declaration from `formats[]` by matching `format_option_id` (recommended; avoids duplication). Top-level formats may be publisher-owned custom formats or narrowed canonical formats; their `format_kind` is the canonical anchor that the placement reference inherits. (2) carry an inline `ProductFormatDeclaration` directly — for placement-specific canonical narrowing that doesn't fit a reusable catalog entry. This bare-reference shape is placement-catalog specific; Product `format_options[]` entries are always full `ProductFormatDeclaration` objects with required `format_kind` and `params`.\n\nProduct-level formats remain the upper bound for a sellable product. Catalog placement formats describe placement support; when a product references the placement and also declares product-level formats, buyers use the intersection for that product placement. A catalog placement format that is absent from the product-level declaration is not accepted for that product unless the product explicitly includes it. When the product locale policy is absent, placement locale_policy may introduce any concrete narrowing; when both are present, every placement accepted_language_range must be contained by a product range under RFC 4647 Basic Filtering. An effective placement policy is canonical-only: its resolved catalog and matching product declarations cannot project through legacy format_ids.\n\n**Format-option reference shape.** A format-option reference entry SHOULD carry ONLY `format_option_id` — extra fields are allowed (`additionalProperties: true`) so adopters who want to attach a placement-local override like `display_name` or a narrower `locale_policy` don't get rejected by the branch boundary, but buyer SDKs MUST resolve the format from the top-level `formats[]` by `format_option_id` and apply additional fields on the entry as placement-level overrides (NOT as a partial inline declaration). If a publisher needs to materially narrow the format at the placement, use the inline-declaration form instead.\n\n**Resolution scope is same-file only.** `format_option_id` resolves only within this file's top-level `formats[]`; cross-file references are not supported by design because same-file resolution keeps validation bounded and prevents a file from squatting on or narrowing another publisher's format_option_id. When `format_options[]` references a `format_option_id` not declared in the file's top-level `formats[]`, validators MUST surface this as `FORMAT_OPTION_UNRESOLVED` on the response `errors[]`. Buyers MUST fail closed for that placement (drop the format from the placement's accepted set) rather than silently dropping the placement or guessing intent.",
            min_length=1,
        ),
    ] = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None,
        Field(
            description='Declared video placement types for this publisher placement, using IAB Tech Lab/OpenRTB 2.6 video.plcmt definitions with AdCP-native names. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. Product-level placement declarations may narrow this set but SHOULD NOT broaden it. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None,
        Field(
            description='Declared audio distribution types for this publisher placement, using IAB Tech Lab/OpenRTB 2.6 audio.feed definitions with AdCP-native names. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. Product-level placement declarations may narrow this set but SHOULD NOT broaden it. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None,
        Field(
            description='Declared sponsored-placement types for this publisher placement, distinguishing where the catalog-driven retail-media placement renders on the retailer surface. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. Product-level placement declarations may narrow this set but SHOULD NOT broaden it. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None,
        Field(
            description='Declared social-placement surfaces for this publisher placement, distinguishing the in-app surface where the social placement renders. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. Product-level placement declarations may narrow this set but SHOULD NOT broaden it. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    identifiers: Annotated[
        list[Identifier] | None,
        Field(
            description='Optional external inventory identifiers for this placement, using the same {type, value} shape as property identifiers. Externally governed IDs should be authority-prefixed (e.g., space:1234931339, geopath:30961, fcc:73953). Seller-local IDs are opaque values scoped by the surrounding publisher namespace. Product-level placement declarations may carry additional identifiers but SHOULD NOT contradict publisher-declared identifiers for the same type.',
            min_length=1,
        ),
    ] = None
    dooh_placement_attributes: PublisherDoohPlacementAttributes | None = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> PlacementDefinition:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('property_ids',), ('property_tags',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'PlacementDefinition requires at least one of these field groups: property_ids | property_tags'
        )

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 audio_distribution_types : list[AudioDistributionType] | None
var channels : list[MediaChannel] | None
var collection_ids : list[str] | None
var description : str | None
var dooh_placement_attributes : PublisherDoohPlacementAttributes | None
var ext : ExtensionObject | None
var format_options : list[typing.Union[FormatOptions, ProductFormatDeclaration1, ProductFormatDeclaration2, ProductFormatDeclaration3, ProductFormatDeclaration4, ProductFormatDeclaration5, ProductFormatDeclaration6, ProductFormatDeclaration7, ProductFormatDeclaration8, ProductFormatDeclaration9, ProductFormatDeclaration10, ProductFormatDeclaration11, ProductFormatDeclaration12, ProductFormatDeclaration13, ProductFormatDeclaration14, ProductFormatDeclaration15, ProductFormatDeclaration16]] | None
var identifiers : list[Identifier] | None
var model_config
var name : str
var placement_id : str
var presentation_ref : PlacementPresentationReference | None
var preview_provider : PublisherDesignatedPreviewProvider | None
var property_ids : list[PropertyId] | None
var property_tags : list[PropertyTag] | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var tags : list[str] | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class PlacementDeliveryMetrics (**data: Any)
Expand source code
class PlacementDeliveryMetrics(DeliveryMetrics):
    placement_identity: Annotated[
        placement_identity_1.PlacementIdentity | None,
        Field(
            description='Self-contained identity. publisher_ref resolves in adagents.json; seller_inline is scoped by seller_agent.'
        ),
    ] = None
    placement_name: Annotated[
        str | None,
        Field(
            description='Current human-readable placement name. Convenience metadata only; placement_identity is stable identity.'
        ),
    ] = None
    placement_id: Annotated[
        str,
        Field(
            description='Required flat compatibility identity. It MUST equal placement_identity.placement_id when placement_identity is present.'
        ),
    ]
    publisher_domain: Annotated[
        str | None,
        Field(
            description='Legacy publisher attribution. For publisher_ref identity it MUST equal placement_identity.publisher_domain. For seller_inline it identifies inventory context only and is not identity authority.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    impressions: Any
    spend: Any

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 impressions : Any
var model_config
var placement_id : str
var placement_identity : PlacementIdentity | None
var placement_name : str | None
var publisher_domain : str | None
var spend : Any

Inherited members

class PlacementEvidence (**data: Any)
Expand source code
class PlacementEvidence(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    url: Annotated[
        AnyUrl,
        Field(
            description='The evidence artifact — photograph, scanned tearsheet, or evidence package'
        ),
    ]
    captured_at: Annotated[
        AwareDatetime | None, Field(description='When the artifact was captured')
    ] = None
    latitude: Annotated[
        StrictFloat | None, Field(description='Capture location latitude', ge=-90.0, le=90.0)
    ] = None
    longitude: Annotated[
        StrictFloat | None, Field(description='Capture location longitude', ge=-180.0, le=180.0)
    ] = None
    notes: Annotated[
        str | None,
        Field(
            description="Context that doesn't fit the structured fields (e.g., 'shot from the eastbound approach at 40mph equivalent')"
        ),
    ] = 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 captured_at : pydantic.types.AwareDatetime | None
var latitude : float | None
var longitude : float | None
var model_config
var notes : str | None
var url : pydantic.networks.AnyUrl

Inherited members

class PlacementForecastDimension (**data: Any)
Expand source code
class PlacementForecastDimension(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Annotated[Literal['placement'], Field(description='Dimension family discriminator.')] = 'placement'
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Structured placement reference for this forecast row. References an entry from the product's placements array."
        ),
    ]
    placement_name: Annotated[
        str | None,
        Field(
            description='Human-readable placement name, useful when the buyer has not resolved the placement catalog.'
        ),
    ] = 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 kind : Literal['adcp.types.domains.core.placement']
var model_config
var placement_name : str | None
var placement_ref : PlacementReference

Inherited members

class PlacementIdentity (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class PlacementIdentity(RootModel[PlacementIdentity1 | PlacementIdentity2]):
    root: Annotated[
        PlacementIdentity1 | PlacementIdentity2,
        Field(
            description='Self-contained identity for either a publisher-catalog placement or a sales-agent-defined inline placement. The discriminator names which authority owns placement_id.',
            title='Placement Identity',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[PlacementIdentity1, PlacementIdentity2]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : PlacementIdentity1 | PlacementIdentity2
class PlacementIdentity1 (**data: Any)
Expand source code
class PlacementIdentity1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['publisher_ref'] = 'publisher_ref'
    publisher_domain: Annotated[
        str,
        Field(
            description='Domain whose adagents.json declares placement_id.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    placement_id: Annotated[str, Field(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 kind : Literal['publisher_ref']
var model_config
var placement_id : str
var publisher_domain : str

Inherited members

class PlacementIdentity2 (**data: Any)
Expand source code
class PlacementIdentity2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['seller_inline'] = 'seller_inline'
    seller_agent: Annotated[
        seller_agent_ref.SellerAgentReference,
        Field(description='Sales agent that defines and maintains the inline placement namespace.'),
    ]
    placement_id: Annotated[
        str,
        Field(
            description="Stable placement ID within the defining sales agent's namespace. The agent MUST NOT reuse it for a different semantic placement.",
            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 kind : Literal['seller_inline']
var model_config
var placement_id : str
var seller_agent : SellerAgentReference

Inherited members

class PlacementPresentationDocument (**data: Any)
Expand source code
class PlacementPresentationDocument(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    schema_version: Literal['1.0'] = '1.0'
    canvas: Canvas
    creative_slot: Annotated[
        CreativeSlot,
        Field(
            description='Rectangle into which the selected creative render is fitted and clipped without changing its manifest or renderer.'
        ),
    ]
    decorations: Annotated[
        list[BoxDecoration | TextDecoration | ImageDecoration] | None, Field(max_length=100)
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var canvas : Canvas
var creative_slot : CreativeSlot
var decorations : list[BoxDecoration | TextDecoration | ImageDecoration] | None
var model_config
var schema_version : Literal['1.0']

Inherited members

class PlacementPresentationReference (**data: Any)
Expand source code
class PlacementPresentationReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    uri: Annotated[
        AnyUrl,
        Field(
            description='Publisher-controlled HTTPS URL for the presentation metadata. Consumers MUST apply the same SSRF, redirect, response-size, timeout, and DNS-rebinding protections used for format_schema fetches.'
        ),
    ]
    digest: Annotated[
        str,
        Field(
            description='SHA-256 content digest. Consumers cache by uri@digest and MUST fail closed on a digest mismatch.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    media_type: Annotated[
        Literal['application/vnd.adcp.placement-presentation+json'],
        Field(description='Media type of the referenced declarative presentation document.'),
    ] = 'application/vnd.adcp.placement-presentation+json'
    schema_version: Annotated[
        Literal['1.0'],
        Field(
            description='Version of /schemas/core/placement-presentation.json used to validate and compose the referenced document.'
        ),
    ] = '1.0'

    @field_validator('uri')
    @classmethod
    def _require_https_uri(cls, value: AnyUrl) -> AnyUrl:
        if value.scheme != 'https':
            raise ValueError('uri must use https')
        return value

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var digest : str
var media_type : Literal['application/vnd.adcp.placement-presentation+json']
var model_config
var schema_version : Literal['1.0']
var uri : pydantic.networks.AnyUrl

Inherited members

class PlacementPropertyDeliveryMetrics (**data: Any)
Expand source code
class PlacementPropertyDeliveryMetrics(DeliveryMetrics):
    placement_id: Annotated[
        str,
        Field(
            description='Required flat compatibility ID. It MUST equal placement_identity.placement_id when placement_identity is present.'
        ),
    ]
    placement_identity: Annotated[
        placement_identity_1.PlacementIdentity,
        Field(
            description='Required self-contained placement identity. Unlike the legacy-compatible by_placement dimension, the new by_placement_property dimension has no pre-3.2 row shape and always names the placement authority.'
        ),
    ]
    placement_name: Annotated[
        str | None, Field(description='Current convenience name for the placement.')
    ] = None
    publisher_domain: Annotated[
        str,
        Field(
            description="Publisher or platform authority that namespaces the property identifier. This may differ from a publisher-catalog placement's publisher_domain.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    identifier: Annotated[
        identifier_1.Identifier,
        Field(description='Primary operational identifier of the property that delivered.'),
    ]
    property_ref: Annotated[
        property_ref_1.PropertyReference | None,
        Field(
            description="Canonical publisher-scoped property catalog identity when available. Its publisher_domain MUST equal the row's publisher_domain."
        ),
    ] = None
    property_name: Annotated[
        str | None, Field(description='Current convenience name for the property.')
    ] = None
    impressions: Any
    spend: Any

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 identifier : Identifier
var impressions : Any
var model_config
var placement_id : str
var placement_identity : PlacementIdentity
var placement_name : str | None
var property_name : str | None
var property_ref : PropertyReference | None
var publisher_domain : str
var spend : Any

Inherited members

class PlacementReference (**data: Any)
Expand source code
class PlacementReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description='Domain where the adagents.json declaring a publisher-catalog placement is hosted, or the inventory publisher associated with an inline placement. Omitted only for legacy single-publisher product-context references.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    placement_id: Annotated[
        str,
        Field(
            description="Placement ID from the publisher's adagents.json placement catalog, or an inline seller-defined placement ID interpreted within the enclosing seller and product context."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var placement_id : str
var publisher_domain : str | None

Inherited members

class PlacementSelection1 (**data: Any)
Expand source code
class PlacementSelection1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['selected'] = 'selected'
    placement_refs: Annotated[
        list[placement_ref.PlacementReference | placement_identity.PlacementIdentity],
        Field(
            description="Complete required placement set. A reference normally identifies a mode targetable placement. It MAY identify a mode included placement only when the set exactly equals the product's complete fixed included set, which is an inherent match rather than independent selection. Legacy publisher refs use {publisher_domain, placement_id}; authority-discriminated 3.2 identities use placement-identity.json so seller-inline inventory is selected by {seller_agent, placement_id}. An item that exactly matches placement-identity uses that canonical identity; otherwise a released-compatible item with publisher_domain and placement_id uses legacy product-context matching, and tolerated product metadata such as kind, name, or mode has no selection effect.",
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var mode : Literal['selected']
var model_config
var placement_refs : list[PlacementReference | PlacementIdentity]

Inherited members

class PlacementSelection2 (**data: Any)
Expand source code
class PlacementSelection2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['default'] = 'default'
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var mode : Literal['default']
var model_config

Inherited members

class PlannedDelivery (**data: Any)
Expand source code
class PlannedDelivery(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    media_buy_id: Annotated[
        str | None,
        Field(
            description='Seller-assigned media buy identifier. Optional on a purchase-phase prepare/check because the service may not assign the identifier until commit; required on modification and delivery lifecycle checks.',
            min_length=1,
        ),
    ] = None
    proposal_id: Annotated[
        str | None,
        Field(
            description='Proposal snapshot being executed or currently governing the MediaBuy.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    proposal_terms_digest: Annotated[
        str | None,
        Field(
            description='Digest of the proposal commercial_terms. The governance agent compares it to the digest bound during the intent check.',
            pattern='^sha256:[A-Za-z0-9_-]{43}$',
        ),
    ] = None
    geo: Annotated[Geo | None, Field(description='Geographic targeting the seller will apply.')] = (
        None
    )
    channels: Annotated[
        list[channels_1.MediaChannel] | None,
        Field(description='Channels the seller will deliver on.'),
    ] = None
    start_time: Annotated[
        AwareDatetime | None, Field(description='Actual flight start the seller will use.')
    ] = None
    end_time: Annotated[
        AwareDatetime | None, Field(description='Actual flight end the seller will use.')
    ] = None
    frequency_cap: Annotated[
        frequency_cap_1.FrequencyCap | None,
        Field(description='Frequency cap the seller will apply.'),
    ] = None
    audience_summary: Annotated[
        str | None,
        Field(description='Human-readable summary of the audience the seller will target.'),
    ] = None
    audience_targeting: Annotated[
        list[audience_selector.AudienceSelector] | None,
        Field(
            description='Structured audience targeting the seller will activate. Each entry is either a signal reference or a descriptive criterion. When present, governance agents MUST use this for bias/fairness validation and SHOULD ignore audience_summary for validation purposes. The audience_summary field is a human-readable rendering of this array, not an independent declaration.',
            min_length=1,
        ),
    ] = None
    total_budget: Annotated[
        StrictFloat | None,
        Field(description='Total budget the seller will deliver against.', ge=0.0),
    ] = None
    daily_budget_cap: Annotated[
        StrictFloat | None,
        Field(
            description='Hard aggregate daily spend ceiling the seller will enforce. Governance checks compare it with the authorized execution controls; it does not allocate spend to packages.',
            ge=0.0,
        ),
    ] = None
    budget_cap_timezone: Annotated[
        str | None,
        Field(
            description='IANA timezone defining the calendar-day boundary for every daily cap on the planned media buy.'
        ),
    ] = None
    currency: Annotated[
        str | None,
        Field(
            description='ISO 4217 currency code for the budget. Governance execution checks require it whenever total_budget is present and require it to match the intent-authorized currency.',
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    budget_allocation: Annotated[
        budget_allocation_1.BudgetAllocation | None,
        Field(
            description='Seller-accepted cross-package allocation authority and goals. Presence with seller_optimized mode means automatic within-buy reallocations are part of the committed delivery, not separate modification actions.'
        ),
    ] = None
    pacing: Annotated[
        pacing_1.Pacing | None,
        Field(description='Aggregate pacing strategy the seller will apply to total_budget.'),
    ] = None
    bidding: Annotated[
        bidding_policy.BiddingPolicy | None,
        Field(
            description='Seller-interpreted media-buy bidding policy used for governance and delivery transparency. Goal-bound controls follow budget-allocation scope semantics and monetary fields use the planned delivery currency. Package-authored overrides, including explicit automatic overrides, remain on packages rather than being copied into this aggregate field.'
        ),
    ] = None
    enforced_policies: Annotated[
        list[str] | None,
        Field(description='Registry policy IDs the seller will enforce for this delivery.'),
    ] = None
    ext: ext_1.ExtensionObject | 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 audience_summary : str | None
var audience_targeting : list[AudienceSelector1 | AudienceSelector2 | AudienceSelector3 | AudienceSelector4] | None
var bidding : BiddingPolicy | None
var budget_allocation : BudgetAllocation1 | BudgetAllocation2 | None
var budget_cap_timezone : str | None
var channels : list[MediaChannel] | None
var currency : str | None
var daily_budget_cap : float | None
var end_time : pydantic.types.AwareDatetime | None
var enforced_policies : list[str] | None
var ext : ExtensionObject | None
var frequency_cap : FrequencyCap | None
var geo : Geo | None
var media_buy_id : str | None
var model_config
var pacing : Pacing | None
var proposal_id : str | None
var proposal_terms_digest : str | None
var start_time : pydantic.types.AwareDatetime | None
var total_budget : float | None

Inherited members

class Platform (*args, **kwds)
Expand source code
class Platform(StrEnum):
    ios = 'ios'
    android = 'android'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var android
var ios
class PlatformExtensionRef (**data: Any)
Expand source code
class PlatformExtensionRef(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    uri: Annotated[
        AnyUrl,
        Field(
            description="HTTPS URL identifying the extension. `https://` is mandatory — `http://`, `file://`, `data:`, and other schemes are rejected at the schema layer (defense-in-depth on top of the fetch-contract normative rules). The URI base is the owning agent's URL; the path identifies the extension within that agent. Example: 'https://creative.adcontextprotocol.org/translated/meta/extensions/meta_pixel'. The full fetch contract — SSRF allowlist, response-size cap, $ref sandbox, schema-compile bounds — is documented on `product-format-declaration.json#format_schema` and applies to ALL fetches of this reference shape regardless of whether the field is named `format_schema` (load-bearing for validation) or `platform_extensions` (informational); the *transport* rules are identical, only the *consumption* semantics differ."
        ),
    ]
    digest: Annotated[
        str,
        Field(
            description='SHA-256 content digest of the extension definition (sha256:<hex>). Used to detect drift — if the agent revises the extension, the digest changes and cached definitions become invalid.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var digest : str
var model_config
var uri : pydantic.networks.AnyUrl

Inherited members

class PlatformExtensionReference (**data: Any)
Expand source code
class PlatformExtensionReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    uri: Annotated[
        AnyUrl,
        Field(
            description="HTTPS URL identifying the extension. `https://` is mandatory — `http://`, `file://`, `data:`, and other schemes are rejected at the schema layer (defense-in-depth on top of the fetch-contract normative rules). The URI base is the owning agent's URL; the path identifies the extension within that agent. Example: 'https://creative.adcontextprotocol.org/translated/meta/extensions/meta_pixel'. The full fetch contract — SSRF allowlist, response-size cap, $ref sandbox, schema-compile bounds — is documented on `product-format-declaration.json#format_schema` and applies to ALL fetches of this reference shape regardless of whether the field is named `format_schema` (load-bearing for validation) or `platform_extensions` (informational); the *transport* rules are identical, only the *consumption* semantics differ."
        ),
    ]
    digest: Annotated[
        str,
        Field(
            description='SHA-256 content digest of the extension definition (sha256:<hex>). Used to detect drift — if the agent revises the extension, the digest changes and cached definitions become invalid.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var digest : str
var model_config
var uri : pydantic.networks.AnyUrl

Inherited members

class Point (**data: Any)
Expand source code
class Point(forecast_point.ForecastPoint):
    dimensions: Annotated[
        forecast_point_dimensions.ForecastPointDimensions,
        Field(
            description='Dimension constraints represented by this forecast point, such as country, region, placement, device type, platform, audience, signal value, time window, or intersections such as placement x country or product x signal. Each item declares one dimension family; when multiple items are present, the point represents their intersection. Sellers MUST NOT emit more than one item for each `kind` on a point; consumers MUST NOT treat repeated kinds as OR semantics. Use multiple points with dimensions to expose country/placement/signal availability within one product, proposal, or signal coverage forecast without creating separate products solely for each dimension. Dimensions describe the forecast row and are independent of pricing_options.'
        ),
    ]
    metrics: Annotated[
        Metrics,
        Field(
            description='Forecasted metric values. Keys are forecastable-metric enum values for delivery/engagement or event-type enum values for outcomes. Values are ForecastRange objects (low/mid/high). Use { "mid": value } for point estimates. When budget is present, these are the expected metrics at that spend level. When budget is omitted, these represent total available inventory — use spend to express the estimated cost. Additional keys beyond the documented properties are allowed for event-type values (purchase, lead, app_install, etc.).'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var dimensions : ForecastPointDimensions
var metrics : Metrics
var model_config

Inherited members

class PolicyProfile (**data: Any)
Expand source code
class PolicyProfile(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    modes: Annotated[
        list[Mode] | None,
        Field(
            description='Standalone policy modes accepted in this exact scope and allocation context. Combination-only components belong only in supported_combinations and need not appear here. `automatic` means the seller accepts and preserves an explicit `{automatic:true}` authored block; omission only invokes inheritance/default behavior.',
            min_length=1,
        ),
    ] = None
    cost_per_strengths: Annotated[
        list[CostPerStrength] | None,
        Field(
            description='Supported standalone cost_per strengths in this profile. Required exactly when modes includes cost_per.',
            min_length=1,
        ),
    ] = None
    roas_strengths: Annotated[
        list[RoasStrength] | None,
        Field(
            description='Supported standalone roas strengths in this profile. Required exactly when modes includes roas.',
            min_length=1,
        ),
    ] = None
    supported_combinations: Annotated[
        list[MaxBidWithCostPer | MaxBidWithRoas] | None,
        Field(
            description='Multi-field policies supported in this exact scope and allocation context. Each entry independently qualifies the strengths supported in that combination; standalone strength support does not imply combination support. Absence means no multi-field combination is claimed.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var cost_per_strengths : list[CostPerStrength] | None
var model_config
var modes : list[Mode] | None
var roas_strengths : list[RoasStrength] | None
var supported_combinations : list[MaxBidWithCostPer | MaxBidWithRoas] | None

Inherited members

class PositivePostalAreaSupport (**data: Any)
Expand source code
class PositivePostalAreaSupport(PostalAreaSupport):
    us_zip: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    us_zip_plus_four: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    gb_outward: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    gb_full: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    ca_fsa: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    ca_full: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    de_plz: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    fr_code_postal: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    au_postcode: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    ch_plz: Annotated[Literal[True] | None, Field(deprecated=True)] = None
    at_plz: Annotated[Literal[True] | None, Field(deprecated=True)] = 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 at_plz : Literal[True] | None
var au_postcode : Literal[True] | None
var ca_fsa : Literal[True] | None
var ca_full : Literal[True] | None
var ch_plz : Literal[True] | None
var de_plz : Literal[True] | None
var fr_code_postal : Literal[True] | None
var gb_full : Literal[True] | None
var gb_outward : Literal[True] | None
var model_config
var us_zip : Literal[True] | None
var us_zip_plus_four : Literal[True] | None

Inherited members

class PostalArea (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class PostalArea(RootModel[PostalArea2 | PostalArea1]):
    root: Annotated[
        PostalArea2 | PostalArea1,
        Field(
            description='Postal area values. Prefer the native country + postal system form. Deprecated legacy country-fused postal-system tokens remain accepted for compatibility.',
            title='Postal Area',
        ),
    ]
    @model_validator(mode='before')
    @classmethod
    def _validate_country_system_pairing(cls, value: Any) -> Any:
        raw = value.get('root', value) if isinstance(value, dict) else value
        country = raw.get('country') if isinstance(raw, dict) else getattr(raw, 'country', None)
        if not isinstance(country, str):
            return value
        system = raw.get('system') if isinstance(raw, dict) else getattr(raw, 'system', None)
        system = getattr(system, 'value', system)
        if not isinstance(system, str):
            return value
        allowed_by_country = {'US': ('zip', 'zip_plus_four'), 'GB': ('outward', 'full'), 'CA': ('fsa', 'full'), 'DE': ('plz',), 'CH': ('plz',), 'AT': ('plz',), 'FR': ('code_postal',), 'AU': ('postcode',), 'BR': ('cep',), 'IN': ('pin',), 'ZA': ('postal_code',)}
        allowed = allowed_by_country.get(country, ('postal_code', 'custom'))
        if system not in allowed:
            raise ValueError(
                f"postal system {system!r} is not valid for country {country!r}; "
                f"expected one of {list(allowed)!r}"
            )
        return value
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[PostalArea2, PostalArea1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : PostalArea2 | PostalArea1
class PostalArea1 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class PostalArea1(
    RootModel[
        PostalArea112
        | PostalArea113
        | PostalArea114
        | PostalArea115
        | PostalArea116
        | PostalArea117
        | PostalArea118
        | PostalArea119
        | PostalArea120
        | PostalArea121
    ]
):
    root: Annotated[
        PostalArea112
        | PostalArea113
        | PostalArea114
        | PostalArea115
        | PostalArea116
        | PostalArea117
        | PostalArea118
        | PostalArea119
        | PostalArea120
        | PostalArea121,
        Field(
            description='Postal area values. Prefer the native country + postal system form. Deprecated legacy country-fused postal-system tokens remain accepted for compatibility.',
            title='PostalArea',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[PostalArea112, PostalArea113, PostalArea114, PostalArea115, PostalArea116, PostalArea117, PostalArea118, PostalArea119, PostalArea120, PostalArea121]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : PostalArea112 | PostalArea113 | PostalArea114 | PostalArea115 | PostalArea116 | PostalArea117 | PostalArea118 | PostalArea119 | PostalArea120 | PostalArea121
class PostalArea11 (**data: Any)
Expand source code
class PostalArea11(AdCPBaseModel):
    country: Annotated[
        Literal['US'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'US'
    system: Annotated[
        System, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : Literal['US']
var model_config
var system : System

Inherited members

class PostalArea110 (**data: Any)
Expand source code
class PostalArea110(AdCPBaseModel):
    country: Annotated[
        str, Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ]
    system: Annotated[
        System9, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : str
var model_config
var system : System9

Inherited members

class PostalArea111 (**data: Any)
Expand source code
class PostalArea111(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    country: Annotated[
        str,
        Field(
            description='ISO 3166-1 alpha-2 country code for the postal values.',
            pattern='^[A-Z]{2}$',
        ),
    ]
    system: Annotated[
        postal_system.PostalCodeSystem,
        Field(
            description="Country-local postal code system (e.g., 'zip', 'outward', 'plz', 'postal_code')."
        ),
    ]
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 country : str
var model_config
var system : PostalCodeSystem
var values : list[str]

Inherited members

class PostalArea112 (**data: Any)
Expand source code
class PostalArea112(PostalArea11):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea113 (**data: Any)
Expand source code
class PostalArea113(PostalArea12):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea114 (**data: Any)
Expand source code
class PostalArea114(PostalArea13):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea115 (**data: Any)
Expand source code
class PostalArea115(PostalArea14):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea116 (**data: Any)
Expand source code
class PostalArea116(PostalArea15):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea117 (**data: Any)
Expand source code
class PostalArea117(PostalArea16):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea118 (**data: Any)
Expand source code
class PostalArea118(PostalArea17):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea119 (**data: Any)
Expand source code
class PostalArea119(PostalArea18):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea12 (**data: Any)
Expand source code
class PostalArea12(AdCPBaseModel):
    country: Annotated[
        Literal['GB'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'GB'
    system: Annotated[
        System1, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : Literal['GB']
var model_config
var system : System1

Inherited members

class PostalArea120 (**data: Any)
Expand source code
class PostalArea120(PostalArea19):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea121 (**data: Any)
Expand source code
class PostalArea121(PostalArea110):
    model_config = ConfigDict(
        extra='forbid',
    )
    values: Annotated[
        list[str], Field(description='Postal codes within the country and system.', 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 model_config
var values : list[str]

Inherited members

class PostalArea13 (**data: Any)
Expand source code
class PostalArea13(AdCPBaseModel):
    country: Annotated[
        Literal['CA'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'CA'
    system: Annotated[
        System2, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : Literal['CA']
var model_config
var system : System2

Inherited members

class PostalArea14 (**data: Any)
Expand source code
class PostalArea14(AdCPBaseModel):
    country: Annotated[Country, Field(description='ISO 3166-1 alpha-2 country code.')]
    system: Annotated[
        Literal['plz'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'plz'

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 country : Country
var model_config
var system : Literal['plz']

Inherited members

class PostalArea15 (**data: Any)
Expand source code
class PostalArea15(AdCPBaseModel):
    country: Annotated[
        Literal['FR'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'FR'
    system: Annotated[
        Literal['code_postal'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'code_postal'

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 country : Literal['FR']
var model_config
var system : Literal['code_postal']

Inherited members

class PostalArea16 (**data: Any)
Expand source code
class PostalArea16(AdCPBaseModel):
    country: Annotated[
        Literal['AU'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'AU'
    system: Annotated[
        Literal['postcode'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'postcode'

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 country : Literal['AU']
var model_config
var system : Literal['postcode']

Inherited members

class PostalArea17 (**data: Any)
Expand source code
class PostalArea17(AdCPBaseModel):
    country: Annotated[
        Literal['BR'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'BR'
    system: Annotated[
        Literal['cep'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'cep'

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 country : Literal['BR']
var model_config
var system : Literal['cep']

Inherited members

class PostalArea18 (**data: Any)
Expand source code
class PostalArea18(AdCPBaseModel):
    country: Annotated[
        Literal['IN'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'IN'
    system: Annotated[
        Literal['pin'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'pin'

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 country : Literal['IN']
var model_config
var system : Literal['pin']

Inherited members

class PostalArea19 (**data: Any)
Expand source code
class PostalArea19(AdCPBaseModel):
    country: Annotated[
        Literal['ZA'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'ZA'
    system: Annotated[
        Literal['postal_code'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'postal_code'

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 country : Literal['ZA']
var model_config
var system : Literal['postal_code']

Inherited members

class PostalArea2 (**data: Any)
Expand source code
class PostalArea2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    system: Annotated[
        legacy_postal_system.CountryFusedPostalCodeSystem,
        Field(
            deprecated=True,
            description="Deprecated country-fused postal code system (e.g., 'us_zip', 'gb_outward'). Prefer country + postal-system.",
        ),
    ]
    values: Annotated[
        list[str], Field(description='Postal codes within the legacy system.', 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 model_config
var system : CountryFusedPostalCodeSystem
var values : list[str]

Inherited members

class PostalAreaSupport (**data: Any)
Expand source code
class PostalAreaSupport(AdCPBaseModel):
    __pydantic_extra__: Dict[
        str, list[PostalAreaSupportAdditionalPropertyEnum]
    ]
    model_config = ConfigDict(
        extra='allow',
    )
    US: Annotated[list[ME] | None, Field(min_length=1)] = None
    GB: Annotated[list[GBEnum] | None, Field(min_length=1)] = None
    CA: Annotated[list[CAEnum] | None, Field(min_length=1)] = None
    DE: Annotated[list[Literal['plz']] | None, Field(min_length=1)] = None
    CH: Annotated[list[Literal['plz']] | None, Field(min_length=1)] = None
    AT: Annotated[list[Literal['plz']] | None, Field(min_length=1)] = None
    FR: Annotated[list[Literal['code_postal']] | None, Field(min_length=1)] = None
    AU: Annotated[list[Literal['postcode']] | None, Field(min_length=1)] = None
    BR: Annotated[list[Literal['cep']] | None, Field(min_length=1)] = None
    IN: Annotated[list[Literal['pin']] | None, Field(min_length=1)] = None
    ZA: Annotated[list[Literal['postal_code']] | None, Field(min_length=1)] = None
    us_zip: Annotated[StrictBool | None, Field(deprecated=True)] = None
    us_zip_plus_four: Annotated[StrictBool | None, Field(deprecated=True)] = None
    gb_outward: Annotated[StrictBool | None, Field(deprecated=True)] = None
    gb_full: Annotated[StrictBool | None, Field(deprecated=True)] = None
    ca_fsa: Annotated[StrictBool | None, Field(deprecated=True)] = None
    ca_full: Annotated[StrictBool | None, Field(deprecated=True)] = None
    de_plz: Annotated[StrictBool | None, Field(deprecated=True)] = None
    fr_code_postal: Annotated[StrictBool | None, Field(deprecated=True)] = None
    au_postcode: Annotated[StrictBool | None, Field(deprecated=True)] = None
    ch_plz: Annotated[StrictBool | None, Field(deprecated=True)] = None
    at_plz: Annotated[StrictBool | None, Field(deprecated=True)] = 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 AT : list[typing.Literal['plz']] | None
var AU : list[typing.Literal['postcode']] | None
var BR : list[typing.Literal['cep']] | None
var CA : list[CAEnum] | None
var CH : list[typing.Literal['plz']] | None
var DE : list[typing.Literal['plz']] | None
var FR : list[typing.Literal['code_postal']] | None
var GB : list[GBEnum] | None
var IN : list[typing.Literal['pin']] | None
var US : list[ME] | None
var ZA : list[typing.Literal['postal_code']] | None
var at_plz : bool | None
var au_postcode : bool | None
var ca_fsa : bool | None
var ca_full : bool | None
var ch_plz : bool | None
var de_plz : bool | None
var fr_code_postal : bool | None
var gb_full : bool | None
var gb_outward : bool | None
var model_config
var us_zip : bool | None
var us_zip_plus_four : bool | None

Inherited members

class PostalAreaSupportAdditionalPropertyEnum (*args, **kwds)
Expand source code
class PostalAreaSupportAdditionalPropertyEnum(StrEnum):
    postal_code = 'postal_code'
    custom = 'custom'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var custom
var postal_code
class PostalCountrySystem1 (**data: Any)
Expand source code
class PostalCountrySystem1(AdCPBaseModel):
    country: Annotated[
        Literal['US'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'US'
    system: Annotated[
        System, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : Literal['US']
var model_config
var system : System

Inherited members

class PostalCountrySystem10 (**data: Any)
Expand source code
class PostalCountrySystem10(AdCPBaseModel):
    country: Annotated[
        str, Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ]
    system: Annotated[
        System19, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : str
var model_config
var system : System19

Inherited members

class PostalCountrySystem2 (**data: Any)
Expand source code
class PostalCountrySystem2(AdCPBaseModel):
    country: Annotated[
        Literal['GB'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'GB'
    system: Annotated[
        System11, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : Literal['GB']
var model_config
var system : System11

Inherited members

class PostalCountrySystem3 (**data: Any)
Expand source code
class PostalCountrySystem3(AdCPBaseModel):
    country: Annotated[
        Literal['CA'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'CA'
    system: Annotated[
        System12, Field(description='Country-local postal code system.', title='Postal Code System')
    ]

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 country : Literal['CA']
var model_config
var system : System12

Inherited members

class PostalCountrySystem4 (**data: Any)
Expand source code
class PostalCountrySystem4(AdCPBaseModel):
    country: Annotated[Country, Field(description='ISO 3166-1 alpha-2 country code.')]
    system: Annotated[
        Literal['plz'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'plz'

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 country : Country
var model_config
var system : Literal['plz']

Inherited members

class PostalCountrySystem5 (**data: Any)
Expand source code
class PostalCountrySystem5(AdCPBaseModel):
    country: Annotated[
        Literal['FR'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'FR'
    system: Annotated[
        Literal['code_postal'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'code_postal'

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 country : Literal['FR']
var model_config
var system : Literal['code_postal']

Inherited members

class PostalCountrySystem6 (**data: Any)
Expand source code
class PostalCountrySystem6(AdCPBaseModel):
    country: Annotated[
        Literal['AU'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'AU'
    system: Annotated[
        Literal['postcode'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'postcode'

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 country : Literal['AU']
var model_config
var system : Literal['postcode']

Inherited members

class PostalCountrySystem7 (**data: Any)
Expand source code
class PostalCountrySystem7(AdCPBaseModel):
    country: Annotated[
        Literal['BR'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'BR'
    system: Annotated[
        Literal['cep'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'cep'

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 country : Literal['BR']
var model_config
var system : Literal['cep']

Inherited members

class PostalCountrySystem8 (**data: Any)
Expand source code
class PostalCountrySystem8(AdCPBaseModel):
    country: Annotated[
        Literal['IN'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'IN'
    system: Annotated[
        Literal['pin'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'pin'

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 country : Literal['IN']
var model_config
var system : Literal['pin']

Inherited members

class PostalCountrySystem9 (**data: Any)
Expand source code
class PostalCountrySystem9(AdCPBaseModel):
    country: Annotated[
        Literal['ZA'], Field(description='ISO 3166-1 alpha-2 country code.', pattern='^[A-Z]{2}$')
    ] = 'ZA'
    system: Annotated[
        Literal['postal_code'],
        Field(description='Country-local postal code system.', title='Postal Code System'),
    ] = 'postal_code'

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 country : Literal['ZA']
var model_config
var system : Literal['postal_code']

Inherited members

class Posting (**data: Any)
Expand source code
class Posting(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    panel_id: Annotated[
        str, Field(description='Panel reference matching one of panels[].identifiers[].id')
    ]
    event_type: Annotated[
        EventType | None,
        Field(
            description='What the record attests: initial posting, rotary rotation to a new face, repair/reposting after damage, or removal at flight end'
        ),
    ] = EventType.posted
    occurred_at: Annotated[
        date,
        Field(
            description='Date the attested event happened. For posted events this is the posting date — display terms customarily run from the average posting date across units.'
        ),
    ]
    evidence: Annotated[
        placement_evidence.PlacementEvidence | None,
        Field(
            description='Evidence artifact for this event (completion photograph); capture time and location ride the artifact'
        ),
    ] = 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 event_type : EventType | None
var evidence : PlacementEvidence | None
var model_config
var occurred_at : datetime.date
var panel_id : str

Inherited members

class Presence (*args, **kwds)
Expand source code
class Presence(StrEnum):
    present = 'present'
    absent = 'absent'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var absent
var present
class PreviewRendererMetadata (**data: Any)
Expand source code
class PreviewRendererMetadata(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    renderer_id: Annotated[
        str, Field(description='Stable implementation identifier.', min_length=1)
    ]
    version: Annotated[
        str,
        Field(
            description='Exact semantic version of the renderer implementation.',
            pattern='^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$',
        ),
    ]
    export: Annotated[
        str,
        Field(
            description='Renderer export or entry-point name used for this render.', min_length=1
        ),
    ]
    rendering_origin: Annotated[
        RenderingOrigin,
        Field(
            description='Informational implementation origin copied from the selected route. It does not grant authority.'
        ),
    ]
    tracking_suppressed: Annotated[
        StrictBool,
        Field(
            description='True only when the produced output cannot initiate impression, click, billing, conversion, viewability, or asset-fetch side effects. Renderers that retain any remote asset URL or navigation MUST emit false.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var export : str
var model_config
var renderer_id : str
var rendering_origin : RenderingOrigin
var tracking_suppressed : bool
var version : str

Inherited members

class Price (**data: Any)
Expand source code
class Price(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    amount: Annotated[
        StrictFloat, Field(description='Monetary amount in the specified currency.', ge=0.0)
    ]
    currency: Annotated[
        str,
        Field(
            description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP').", pattern='^[A-Z]{3}$'
        ),
    ]
    period: Annotated[
        Period | None,
        Field(
            description="Billing period. 'night' for hotel rates, 'month' or 'year' for salaries and rentals, 'one_time' for purchase prices. Omit when the period is obvious from context (e.g., a vehicle price is always one-time)."
        ),
    ] = 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 amount : float
var currency : str
var model_config
var period : Period | None

Inherited members

class PricingModel (*args, **kwds)
Expand source code
class PricingModel(StrEnum):
    cpm = 'cpm'
    vcpm = 'vcpm'
    cpc = 'cpc'
    cpcv = 'cpcv'
    cpv = 'cpv'
    cpp = 'cpp'
    cpa = 'cpa'
    revenue_share = 'revenue_share'
    flat_rate = 'flat_rate'
    time = 'time'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var cpa
var cpc
var cpcv
var cpm
var cpp
var cpv
var flat_rate
var revenue_share
var time
var vcpm
class PrincipalChangedWebhook (**data: Any)
Expand source code
class PrincipalChangedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Sender-generated key stable across retries of the same fire. Sellers MUST generate a cryptographically random value (UUID v4 recommended) per distinct fire and reuse it on every retry of the same fire. Receivers MUST dedupe by this key, scoped to the authenticated sender identity.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Stable identifier for this logical principal-state transition. Re-emissions of the same transition reuse this value under a new idempotency_key; a later distinct transition receives a new id.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Annotated[
        Literal['principal.changed'],
        Field(
            description="Fixed notification type discriminator. Matches the value registered on the subscriber's `event_types`."
        ),
    ] = 'principal.changed'
    fired_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller initiated this fire. Distinct from `changed_at`, which is when the seller recorded the state transition.'
        ),
    ]
    subscriber_id: Annotated[
        str,
        Field(
            description="Identifies which caller-scoped notification_configs[] entry is receiving this fire. Echoed verbatim from the entry's subscriber_id.",
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='Canonical seller agent URL whose principal state changed. Receivers connected to multiple agents use this to select which principal record to re-read.'
        ),
    ]
    changed_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller recorded the principal-state transition.'
        ),
    ]
    reason: Annotated[
        Reason,
        Field(
            description='Coarse reason for the invalidation. Advisory routing/debug metadata; receivers MUST re-read get_principal rather than inferring the new state from the reason.'
        ),
    ]
    destination_id: Annotated[
        str | None,
        Field(
            description='Optional advisory hint naming the affected reporting destination for destination-scoped reasons. Receivers MAY use it for selective handling but MUST still treat the get_principal read as authoritative.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 agent_url : pydantic.networks.AnyUrl
var changed_at : pydantic.types.AwareDatetime
var destination_id : str | None
var ext : ExtensionObject | None
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var model_config
var notification_id : str
var notification_type : Literal['principal.changed']
var reason : Reason
var subscriber_id : str

Inherited members

class PrincipalDeclarationsState (**data: Any)
Expand source code
class PrincipalDeclarationsState(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    declared: Annotated[
        principal_declarations.AgentDeclarations,
        Field(description="The caller's current declared set, echoed verbatim."),
    ]
    accepted: Annotated[
        principal_declarations.AgentDeclarations,
        Field(
            description="The intersection of the declared set with the seller's objective support. Sellers select asynchronous payload versions, signing algorithms, and experimental behavior only from this set. A change to this set caused by seller-side evolution fires principal.changed with reason declarations_intersection_changed."
        ),
    ]
    selected_async_adcp_version: Annotated[
        str | None,
        Field(
            description='The single AdCP minor version the seller will use for asynchronous payload shapes toward this principal. MUST be a member of accepted.async_adcp_versions and MUST be present whenever that set is non-empty, so the buyer knows the exact payload contract rather than inferring it from the intersection.',
            pattern='^\\d+\\.\\d+$',
        ),
    ] = None
    exclusions: Annotated[
        list[Exclusion] | None,
        Field(
            description="Every declared value that is absent from the accepted intersection, with the seller's reason. Present whenever declared and accepted differ, so a buyer can see why a capability it relies on was not accepted instead of diffing the two sets.",
            max_length=64,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var accepted : AgentDeclarations
var declared : AgentDeclarations
var exclusions : list[Exclusion] | None
var model_config
var selected_async_adcp_version : str | None

Inherited members

class PrincipalState (**data: Any)
Expand source code
class PrincipalState(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    notification_configs: Annotated[
        list[agent_notification_config_state.AgentNotificationConfigState] | None,
        Field(
            description='Current agent-level webhook subscribers. authentication.credentials is always omitted because it is write-only.',
            max_length=16,
        ),
    ] = None
    reporting_destinations: Annotated[
        list[agent_reporting_destination_state.AgentReportingDestinationState] | None,
        Field(
            description='Current reusable reporting destination bindings and setup states. destination_id and destination_ref values MUST each be unique within this caller-scoped array; superseded generations of a current destination appear in its prior_destination_refs.',
            max_length=64,
        ),
    ] = None
    declarations: Annotated[
        principal_declarations_state.PrincipalDeclarationsState | None,
        Field(
            description='Declared consumption facts and the seller-computed accepted intersection. Present when and only when the seller supports the declarations section.'
        ),
    ] = None
    retired_destinations: Annotated[
        list[RetiredDestination] | None,
        Field(
            description='Destinations the caller revoked by omitting them from a submitted reporting_destinations section, retained while any generation remains resolvable for reporting history. Enumerable only by the owning principal. Reusing a retired destination_id requires fresh registration and proof and produces a new generation.',
            max_length=64,
        ),
    ] = 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 declarations : PrincipalDeclarationsState | None
var model_config
var notification_configs : list[AgentNotificationConfigState] | None
var reporting_destinations : list[AgentReportingDestinationState] | None
var retired_destinations : list[RetiredDestination] | None

Inherited members

class PriorDestinationRef (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class PriorDestinationRef(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 255, 'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ProducerIdentity (**data: Any)
Expand source code
class ProducerIdentity(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    provider: Provider
    identity: Annotated[str, Field(max_length=512, min_length=1)]
    cloud: reporting_dataset_share_destination.ReportingCloud | None = None
    region: Annotated[str | None, Field(max_length=128, min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var cloud : ReportingCloud | None
var identity : str
var model_config
var provider : Provider
var region : str | None

Inherited members

class Product (**data: Any)
Expand source code
class Product(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )


    @model_validator(mode='before')
    @classmethod
    def _coerce_publisher_property_models(cls, data: Any) -> Any:
        if isinstance(data, dict) and isinstance(data.get('publisher_properties'), list):
            coerced = []
            changed = False
            for item in data['publisher_properties']:
                if hasattr(item, 'model_dump'):
                    coerced.append(item.model_dump(mode='json', exclude_none=True))
                    changed = True
                else:
                    coerced.append(item)
            if changed:
                data = dict(data)
                data['publisher_properties'] = coerced
        return data
    product_id: Annotated[
        str,
        Field(
            description='Opaque identifier for this buyable product. For a non-custom wholesale product, sellers MUST reuse the ID for the same logical catalog offer within the seller and declared cache_scope across reads and wholesale-feed webhooks; feed and pricing versions communicate temporal catalog mutation, while retirement or replacement may end the identity. Concurrent or request-bound configurations whose effective targeting, disclosed targeting modifications, forecast assumptions, terms, or overlay support differ MUST use distinguishable configured product IDs. For is_custom: true, the ID identifies only the request-specific discovery/refinement lineage and is not stable across independent contexts. Sellers MUST keep every issued configured ID resolvable for its promised lifetime. Pricing variants within one logical product are distinguished by pricing_option_id: a seller MUST mint a new pricing_option_id whenever a binding fixed price, floor, currency, model, or priced applicability changes, and MUST NOT reinterpret an issued option ID at a new price. Selecting product_id plus pricing_option_id in create_media_buy accepts that returned configuration and commercial option.'
        ),
    ]
    name: Annotated[str, Field(description='Human-readable product name')]
    description: Annotated[
        str, Field(description='Detailed description of the product and its inventory')
    ]
    publisher_properties: Annotated[
        list[PublisherProperty],
        Field(
            description="SDK implementers MUST enforce singular-only at runtime: each entry uses the singular `publisher_domain` form; the compact `publisher_domains[]` form is rejected on products. Codegen toolchains (json-schema-to-typescript, quicktype, datamodel-code-generator, openapi-typescript-codegen) often flatten the `allOf + $ref + not.required` restriction below poorly and may drop the rejection constraint silently, emitting an unrestricted type — runtime enforcement is the safety net. Publisher properties covered by this product. Buyers fetch actual property definitions from each publisher's adagents.json and validate agent authorization. Selection patterns mirror the authorization patterns in adagents.json for consistency. The compact `publisher_domains[]` form is reserved for adagents.json `authorized_agents[].publisher_properties[]` so that buy-side traffic-and-pricing flatteners can always treat each entry as exactly one publisher.",
            min_length=1,
        ),
    ]
    channels: Annotated[
        list[channels_1.MediaChannel] | None,
        Field(
            description="Advertising channels this product is sold as. Products inherit from their properties' supported_channels but may narrow the scope. For example, a product covering YouTube properties might be sold as ['ctv'] even though those properties support ['olv', 'social', 'ctv']."
        ),
    ] = None
    format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Legacy named-format compatibility path. Products MUST carry `format_ids`, `format_options`, or both during the 3.x migration window. New products MUST author canonical `format_options[]`; sellers MAY additionally project those declarations to `format_ids` for legacy buyers. When both fields are present they MUST describe the same underlying formats, and buyers MUST prefer `format_options`. Do not author a new product from `format_ids` alone.',
        ),
    ] = None
    format_options: Annotated[
        list[product_format_declaration.ProductFormatDeclaration] | None,
        Field(
            description="Canonical format-option path: one or more inline format declarations the product accepts. Each element narrows a canonical format with parameters, slots, platform_extensions, and optional locale_policy. New 3.2 products MUST carry format_options; a seller MAY additionally project the same declarations to deprecated format_ids for older 3.x peers. A declaration carrying locale_policy is canonical-only because legacy format_ids cannot preserve locale eligibility; no product or placement format_id may project to an effective locale-constrained option.\n\nWhen placements are published, product-level format_options are the union of formats deliverable somewhere in the product and the upper bound for every placement. A placement's effective accepted set is the intersection of every applicable layer: (1) the product format_options; (2) the product placement's inline format_options, when present; and (3) for kind publisher_ref, the named publisher's adagents.json catalog narrowing. Resolve layer 3 by locating the matching placements[] entry: use its format_options when present, resolving bare format_option_id references against that same file's top-level formats[]; otherwise use top-level formats[] applicable to the placement's property_ids/property_tags. An omitted optional layer is unconstrained, but an unresolved publisher placement or format-option reference MUST fail closed. A publisher-referenced placement without inline product format_options therefore does NOT inherit the full product union when the publisher catalog supplies narrower placement or property-scoped acceptance.\n\nMatch publisher-declared options by {publisher_domain, format_option_id}, match product-local options by format_option_id when publisher_domain is omitted, and otherwise match declarations with the same format_kind whose narrower parameters satisfy the broader declaration. A product- or placement-level declaration MUST NOT introduce a format outside the product upper bound. Locale policy follows the same intersection. If the product locale policy is absent, a placement may introduce any concrete policy as a narrowing of an unconstrained option; when both are present, every placement range must be contained by a product range under RFC 4647 Basic Filtering. Locale eligibility is checked independently for every placement where an assignment may serve.\n\nFor a product or package containing multiple included placements, a single creative intended for every placement MUST lie in the intersection of every selected placement's effective set. Distinct per-placement creatives MAY use the union, but the selected creative set MUST cover every included placement; uncovered inventory MUST be rejected or refined, never silently omitted. If a product spans multiple publishers but omits placements[], there is no public routing key for per-placement creatives: its format_options MUST therefore be the common intersection accepted across every selected publisher/property scope. A seller that needs a union of publisher-specific formats MUST publish placements[] with publisher-scoped identities and narrowing. Commercial terms such as price, floor, availability, and deal eligibility are product facts, not format parameters.",
            min_length=1,
        ),
    ] = None
    placements: Annotated[
        list[placement.Placement] | None,
        Field(
            description="Optional array of specific public placements within this product. Product placements declare `kind` to distinguish publisher-catalog placements (`publisher_ref`) from sales-agent-defined placements (`seller_inline`). Publisher references use canonical `{publisher_domain, placement_id}` identity and may omit name because adagents.json resolves it. New seller-inline placements SHOULD carry `seller_agent`; legacy rows without it remain scoped to the enclosing seller and product. A seller-inline publisher_domain is inventory attribution, not authority to mint an ID in that publisher's catalog namespace. Each placement MUST declare mode: targetable or included. Creative assignments route creatives only after placement inventory is purchased.",
            min_length=1,
        ),
    ] = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None,
        Field(
            description='Declared video placement types that may be included in this product, using IAB Tech Lab/OpenRTB 2.6 video.plcmt definitions with AdCP-native names. Use on OLV, CTV, and other video products when buyers need to distinguish instream, accompanying-content, interstitial, and standalone/no-content inventory. Aggregate products and ad-network products MAY declare multiple values. When `placements[]` also carry `video_placement_types`, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None,
        Field(
            description='Declared audio distribution types that may be included in this product, using IAB Tech Lab/OpenRTB 2.6 audio.feed definitions with AdCP-native names. Use on radio, streaming-audio, podcast, gaming, and other audio products when buyers need to distinguish music streaming services, FM/AM broadcast, podcasts, catch-up radio, web radio, video-game audio, and text-to-speech inventory without changing the buyer-facing channel or adagents.json property type. Aggregate products and ad-network products MAY declare multiple values. When `placements[]` also carry `audio_distribution_types`, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None,
        Field(
            description='Declared sponsored-placement types that may be included in this product, distinguishing where catalog-driven retail-media placements render on the retailer surface (sponsored search, sponsored display, or sponsored native). Use on retail-media products when buyers need to distinguish search-keyed, display, and native in-grid sponsored inventory. Aggregate products and ad-network products MAY declare multiple values. When `placements[]` also carry `sponsored_placement_types`, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None,
        Field(
            description='Declared social-placement surfaces that may be included in this product, distinguishing the in-app surface where social placements render (feed, stories, short_video, explore, or search). Use on social products when buyers need to distinguish feed, story, short-video, and discovery surfaces. Aggregate products and ad-network products MAY declare multiple values. When `placements[]` also carry `social_placement_surfaces`, this product-level array SHOULD be the union of the placement-level declarations the seller may deliver under the product. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.',
            min_length=1,
        ),
    ] = None
    delivery_type: delivery_type_1.DeliveryType
    exclusivity: Annotated[
        exclusivity_1.Exclusivity | None,
        Field(
            description="Whether this product offers exclusive access to its inventory. Defaults to 'none' when absent. Most relevant for guaranteed products tied to specific collections or placements."
        ),
    ] = None
    pricing_options: Annotated[
        list[pricing_option.PricingOption],
        Field(
            description="Available pricing models for this product. Fixed prices and auction floors are binding for every later targeting selection permitted by this product's overlay_support; price_guidance remains non-binding. Declaring broad overlay support alongside a binding option is therefore a uniform-price promise, not permission to calculate a different price at create time. A seller with value-dependent rates MUST return a request-specific configured product after rediscovery with concrete targeting, split the inventory into separately priced products, or expose only non-binding guidance until it can issue a binding option. The seller MUST mint a new pricing_option_id whenever a binding price, floor, currency, model, or priced applicability changes. It MUST NOT silently reprice a create request or reuse the selected option ID with different terms.",
            min_length=1,
        ),
    ]
    forecast: Annotated[
        delivery_forecast.DeliveryForecast | None,
        Field(
            description="Forecasted delivery metrics for this product. Concrete discovery targeting scopes the forecast to those effective values. When discovery requested only required_overlay_support for a dimension, the forecast describes the product's discovery/default scope and is not a value-specific forecast for every later selection; buyers rediscover with concrete targeting_overlay values when they need that forecast."
        ),
    ] = None
    outcome_measurement: Annotated[
        outcome_measurement_1.OutcomeMeasurement | None,
        Field(
            deprecated=True,
            description='**Deprecated as of this minor.** Outcome capabilities (incremental sales lift, brand lift, foot traffic, etc.) are now declared via `reporting_capabilities.available_metrics` (the same path used for impressions, conversions, ROAS) with `qualifier.attribution_methodology` and `qualifier.attribution_window` carrying the methodology and window on commit. New implementations SHOULD use the unified pattern; this field is retained for one-minor backwards compatibility and removed at the next major. See `outcome-measurement.json` description for migration guidance.',
        ),
    ] = None
    delivery_measurement: Annotated[
        DeliveryMeasurement | None,
        Field(
            description='Measurement vendors and methodology for delivery metrics. The buyer accepts the declared vendors as the source of truth for the buy. When absent, buyers should apply their own measurement defaults. Senders SHOULD populate `vendors` (structured BrandRef array) for new implementations; the legacy `provider` string field is deprecated and retained for one-minor backwards compatibility.'
        ),
    ] = None
    measurement_terms: Annotated[
        measurement_terms_1.MeasurementTerms | None,
        Field(
            description="Seller's default billing measurement and makegood terms. Declares who counts the billing metric and what remedies apply when thresholds are breached. Buyers may propose different terms at media buy creation — sellers accept, reject (TERMS_REJECTED), or adjust per their policy."
        ),
    ] = None
    performance_standards: Annotated[
        list[performance_standard.PerformanceStandard] | None,
        Field(
            description="Seller's default performance standards for this product: viewability, IVT, completion rate, brand safety, attention score. Buyers may propose different standards at media buy creation. When absent, no structured performance standards apply.",
            min_length=1,
        ),
    ] = None
    cancellation_policy: Annotated[
        cancellation_policy_1.CancellationPolicy | None,
        Field(
            description='Cancellation terms for this product. Declares the minimum notice period required before cancellation takes effect and any penalties for insufficient notice. Relevant for guaranteed delivery products. Buyers accept these terms by creating a media buy against the product.'
        ),
    ] = None
    allowed_actions: Annotated[
        list[product_allowed_action.ProductAllowedAction] | None,
        Field(
            description='Actions buyers may perform on buys created against this product, scoped to statuses and modes. Advisory template — the authoritative per-buy capability is `available_actions[]` on the buy response, which resolves modes against current buy state, account tier, and negotiated terms. Buyers SHOULD use this for pre-flight product selection ("which products let me self-serve cancel within 72hr?") and read `available_actions[]` for runtime decisions. The array is uniquely keyed by `action` — sellers MUST NOT emit two entries with the same `action` value. Absence means the seller has not declared a structured action surface for this product — buyers fall back to `valid_actions[]` on buy responses for the flat string vocabulary.',
            min_length=1,
        ),
    ] = None
    reporting_capabilities: reporting_capabilities_1.ReportingCapabilities
    creative_policy: creative_policy_1.CreativePolicy | None = None
    is_custom: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product is a request-specific configured offer rather than a reusable baseline product. Sellers MUST set true when targeting, disclosed resolution, pricing, forecast assumptions, inventory, or terms are bound for a particular discovery/refinement lineage. Products issued through targeting-aware discovery include expires_at even when exact acceptance omits targeting_resolution. For backward compatibility, is_custom alone does not make expires_at schema-required.'
        ),
    ] = None
    property_targeting_allowed: Annotated[
        StrictBool | None,
        Field(
            description="Whether buyers can select a subset of this product's publisher_properties through targeting_overlay.property_list. When false, the product is fixed inventory: it matches requested property targeting only when its inherent property set already satisfies the request, or when a configured product discloses additional inventory through targeting_resolution."
        ),
    ] = False
    data_provider_signals: Annotated[
        list[data_provider_signal_selector.DataProviderSignalSelector] | None,
        Field(
            deprecated=True,
            description='Deprecated. Legacy/non-selectable metadata for data-provider signals already bundled into or associated with this product. This field does not provide buyer-selectable options, prices, or seller activation handles. Use included_signals for non-selectable product signal metadata, or signal_targeting_options for selectable package-level signal groups.',
        ),
    ] = None
    included_signals: Annotated[
        list[signal_listing.SignalListing] | None,
        Field(
            description="Non-selectable signal metadata for signals already included in, bundled with, or planned into this product. These signals describe what the product is; buyers do not select them in packages[].targeting_overlay.signal_targeting_groups and this field does not imply package-level signal targeting. Use signal_ref scope 'data_provider' or 'signal_source' to reference externally defined signals without redefining their name or value_type. Use signal_ref scope 'product' with name and value_type when the included signal is defined only by this product.",
            min_length=1,
        ),
    ] = None
    signal_targeting_options: Annotated[
        list[product_signal_targeting_option.ProductSignalTargetingOption] | None,
        Field(
            description="Inline seller-offered signals that may be applied to packages for this product at create_media_buy time. Each entry references a named signal definition with signal_ref scope 'product' for a product-local signal option, scope 'data_provider' for an external signal definition published in adagents.json signals[] that the seller is authorized to apply, or scope 'signal_source' for a source-native signal. Product-local options define name and value_type inline; data-provider and signal-source options may omit those fields when the referenced definition or source is authoritative. Use this field when the selectable menu is product-specific, has product-specific pricing or activation handles, is the relevant subset for a brief/refine result, or should be rendered without an additional get_signals call. Wholesale products may omit this field and rely on get_signals for the selectable signal feed. Buyers select eligible signals through packages[].targeting_overlay.signal_targeting_groups when signal_targeting_rules allow; fixed/default entries are applied by the seller and echoed on the package state. Sellers MUST set signal_targeting_allowed to true whenever this field is present. Bundled, non-selectable signal metadata belongs in included_signals; legacy data_provider_signals may appear only for backwards compatibility.",
            min_length=1,
        ),
    ] = None
    signal_targeting_rules: Annotated[
        signal_targeting_rules_1.SignalTargetingRules | None,
        Field(
            description='Composition rules for selecting signals on this product. The selectable signal menu may come from inline signal_targeting_options or from get_signals when a wholesale product omits inline options. This is product-scoped because products may be backed by different ad servers with different Boolean targeting support and group limits.'
        ),
    ] = None
    signal_targeting_allowed: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product has a package-level signal_targeting_groups surface. When false (default), signals are bundled into the product terms and cannot be selected or explicitly echoed as package signal groups. When true, eligible signals from inline signal_targeting_options or from get_signals may be buyer-selected or seller-applied according to signal_targeting_rules and are represented through packages[].targeting_overlay.signal_targeting_groups. Editability is controlled by signal_targeting_rules; fixed/default-only products still set this to true when applied signal groups are echoed.'
        ),
    ] = False
    demographic_targeting: Annotated[
        demographic_targeting_capability.DemographicTargetingCapability | None,
        Field(
            description='Exact demographic execution available for this product. Buyers MUST use this product-scoped declaration, not the seller-wide get_adcp_capabilities rollup, to preflight a demographic predicate.'
        ),
    ] = None
    overlay_support: Annotated[
        targeting_overlay_support.TargetingOverlaySupport | None,
        Field(
            description='Binding product-scoped targeting dimensions the buyer may set independently on packages after discovery. Presence guarantees selectable capability subject to disclosed limits, not inventory or a forecast for every possible value. Targeting satisfied only through inherent product scope does not appear here. Returned products MUST cover every field requested through get_products.required_overlay_support. A later supported selection with no available inventory returns PRODUCT_UNAVAILABLE on create; an update outside the original priced envelope may return REQUOTE_REQUIRED.'
        ),
    ] = None
    media_buy_support: Annotated[
        media_buy_support_1.ProductMediaBuySupport | None,
        Field(
            description='Binding product participation in shared MediaBuy-level controls. This is separate from overlay_support because a root frequency cap aggregates exposures across packages rather than targeting one package. Returned products MUST cover every field requested through required_media_buy_support.'
        ),
    ] = None
    identity: product_identity.ProductIdentity | None = None
    execution_requirements: Annotated[
        list[product_execution_requirement.ProductExecutionRequirement] | None,
        Field(
            description="Experimental (`media_buy.execution_requirements`). Account resources a package on this product needs before `create_media_buy` succeeds. Every entry is required. Account-independent: it does not change `cache_scope` and carries no account resource IDs or names. When present, it plus the `required_connections` of the package's selected format declarations is complete for the kinds in `product-execution-requirement.json`: a seller MUST NOT reject a package that satisfies all of them for lacking an undeclared kind. Absence means undeclared. A declaring seller MUST reject an unmet `event_source` or `catalog` entry on a buyer-supplied `create_media_buy` `packages[]` or `update_media_buy` `new_packages[]` entry, or an update that removes a satisfying binding, with `VALIDATION_ERROR`, `error.field` at the binding, and `error.details` per `error-details/execution-requirement-unmet.json`.",
            min_length=1,
        ),
    ] = None
    targeting_resolution: Annotated[
        product_targeting_resolution.ProductTargetingResolution | None,
        Field(
            description='Discovery-time targeting resolution bound to this configured product. modifications sparsely disclose product-specific differences from get_products.targeting_overlay. Request-level brief interpretation is returned once on GetProductsResponse.targeting_resolution. Exact structured overlay values are not repeated. Selecting product_id accepts the disclosed modifications; product forecast and pricing MUST reflect them.'
        ),
    ] = None
    audience_evidence: Annotated[
        list[audience_evidence_1.AudienceEvidence] | None,
        Field(
            description='Immutable population-level evidence explaining why this inventory may suit an audience. This supports discovery, comparison, and planning only. It does not imply exact demographic targeting, user-level signal membership, or legal-age verification. Sellers MUST publish each distinct snapshot with a new snapshot_id and content_digest.',
            min_length=1,
        ),
    ] = None
    audience_evidence_selections: Annotated[
        list[audience_evidence_selection.AudienceEvidenceSelection] | None,
        Field(
            description='Exact evidence snapshots that satisfied required eligibility or affected seller ranking for this get_products result. When audience_evidence_requirements was supplied and evidence influenced inclusion or rank, sellers MUST return the relevant selections; an absent-evidence match under evidence_presence when_available has no selection. Product selections use decision_use recommendation or eligibility.',
            min_length=1,
        ),
    ] = None
    catalog_types: Annotated[
        list[catalog_type.CatalogType] | None,
        Field(
            description='Catalog types this product supports for catalog-driven campaigns. A sponsored product listing declares ["product"], a job board declares ["job", "offering"]. Buyers match synced catalogs to products via this field.',
            min_length=1,
        ),
    ] = None
    metric_optimization: Annotated[
        MetricOptimization | None,
        Field(
            description="Metric optimization capabilities for this product. Presence indicates the product supports optimization_goals with kind: 'metric'. No event source or conversion tracking setup required — the seller tracks these metrics natively."
        ),
    ] = None
    vendor_metric_optimization: Annotated[
        vendor_metric_optimization_1.VendorMetricOptimization | None,
        Field(
            description="Vendor-attested metric optimization capabilities for this product. Presence indicates the product supports `optimization_goals` with `kind: 'vendor_metric'` — the seller's bidding stack can steer delivery toward a specific vendor's measurement (e.g., DV/IAS/Adelaide attention, Scope3 emissions, Kantar brand lift, retail-media partner metrics). Distinct from `metric_optimization` (seller-native metrics with no vendor binding) and from `reporting_capabilities.vendor_metrics` (which declares what the product can *report* rather than what it can *optimize against*). A product may report a vendor metric without being able to optimize for it. Buyers MUST verify the goal's `(vendor, metric_id)` is in `supported_metrics` AND that the package's `committed_metrics[]` includes a matching `{ scope: 'vendor', vendor, metric_id }` entry — optimization without committed reporting is unverifiable and is rejected at the wire level."
        ),
    ] = None
    max_optimization_goals: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of optimization_goals this product accepts on a package. When absent, no limit is declared. Most social platforms accept only 1 goal — buyers sending arrays longer than this value should expect the seller to use only the highest-priority (lowest priority number) goal.',
            ge=1,
        ),
    ] = None
    measurement_readiness: Annotated[
        measurement_readiness_1.MeasurementReadiness | None,
        Field(
            description="Assessment of whether the buyer's event source setup is sufficient for this product to optimize effectively. Only present when the seller can evaluate the buyer's account context. Buyers should check this before creating media buys with event-based optimization goals."
        ),
    ] = None
    conversion_tracking: Annotated[
        ConversionTracking | None,
        Field(
            description="Conversion event tracking for this product. Presence indicates the product supports optimization_goals with kind: 'event'. Seller-level capabilities (supported event types, UID types, attribution windows) are declared in get_adcp_capabilities."
        ),
    ] = None
    catalog_match: Annotated[
        CatalogMatch | None,
        Field(
            description='When the buyer provides a catalog on get_products, indicates which catalog items are eligible for this product. Only present for products where catalog matching is relevant (e.g., sponsored product listings, job boards, hotel ads).'
        ),
    ] = None
    brief_relevance: Annotated[
        str | None,
        Field(
            description='Explanation of why this product matches the brief (only included when brief is provided)'
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Expiration timestamp. Required for request-specific configured products whose targeting resolution, price, forecast, inventory, or terms are time-bound. After this time, a seller that still recognizes the issued configured ID within the authenticated account and referenced discovery/refinement lineage rejects create_media_buy with PRODUCT_EXPIRED and the buyer re-runs get_products. Once the seller no longer retains an expiry tombstone, or whenever the ID belongs to another account or lineage, PRODUCT_NOT_FOUND applies instead; sellers are not required to retain tombstones indefinitely and MUST NOT disclose cross-tenant existence through error choice.'
        ),
    ] = None
    product_card: Annotated[
        ProductCard | None,
        Field(
            description='Optional standard visual card for displaying this product in user interfaces (catalog browsers, dashboards, agent UIs). Distinct from `format` — product_card describes the UI rendering of the product itself, not the ad creative the product accepts. Typed inline; no format_id indirection. Receivers render the card directly from these fields.'
        ),
    ] = None
    product_card_detailed: Annotated[
        ProductCardDetailed | None,
        Field(
            description='Optional detailed card with hero + carousel + structured specifications, for rich product presentation (media-kit-style pages, full product detail views). Distinct from `format` — describes the UI rendering of the product itself, not the ad creative the product accepts. Typed inline; no format_id indirection.'
        ),
    ] = None
    collections: Annotated[
        list[collection_selector.CollectionSelector] | None,
        Field(
            description='Collections available in this product. Each entry references collections declared in an adagents.json by domain and collection ID. Buyers resolve full collection objects from the referenced adagents.json. Product selectors must name explicit collection_ids — the domain-only bulk-grant selector form is for authorization scoping, not product composition.',
            min_length=1,
        ),
    ] = None
    collection_targeting_allowed: Annotated[
        StrictBool | None,
        Field(
            description="Whether buyers can select a subset of this product's collections through targeting_overlay.collection_list or targeting_overlay.collection_selection. When false, the product is a fixed bundle (a collection_selection that exactly restates the complete bundle remains an inherent match); when true, collection selection is a product-scoped overlay capability."
        ),
    ] = False
    list_applications: Annotated[
        list[inventory_list_application.InventoryListApplication] | None,
        Field(
            description='Product-scoped receipts for every effective property- or collection-list targeting reference. Sellers MUST return one receipt per application regardless of response field projection; exclusion applications receive a receipt even when summary.matched is zero, while zero matches for any inclusion application make the product ineligible and it is not returned. Each receipt uses the same pre-list product inventory baseline; pricing and forecast reflect inventory remaining after all effective lists are composed.',
            min_length=1,
        ),
    ] = None
    installments: Annotated[
        list[installment.Installment] | None,
        Field(
            description='Specific installments included in this product. Each installment references its parent through canonical collection_ref when the product spans multiple collections or publisher namespaces; collection_id remains a deprecated single-namespace shorthand. When absent with collections present, the product covers the collections broadly (run-of-collection).'
        ),
    ] = None
    enforced_policies: Annotated[
        list[str] | None,
        Field(
            description='Registry policy IDs the seller enforces for this product. Enforcement level comes from the policy registry. Buyers can filter products by required policies.'
        ),
    ] = None
    acceptance_policy_profile_ids: (
        acceptance_policy_profile_ids_1.AcceptancePolicyProfileIds | None
    ) = None
    trusted_match: Annotated[
        TrustedMatch | None,
        Field(
            description='Trusted Match Protocol capabilities for this product. When present, the product supports real-time contextual and/or identity matching via TMP. Buyers use this to determine what response types the publisher can accept and whether brands can be selected dynamically at match time.'
        ),
    ] = None
    audience_activation: Annotated[
        AudienceActivation | None,
        Field(
            description="How buyer audience data can reach this product's targeting. Absence means undeclared — buyers SHOULD treat it as needs-clarification rather than non-support, except under an audience_activation_methods filter, where sellers MUST exclude undeclared products. Declare when the product accepts buyer audiences. Experimental: sellers declaring this MUST list media_buy.audience_activation in experimental_features on get_adcp_capabilities."
        ),
    ] = None
    material_submission: Annotated[
        MaterialSubmission | None,
        Field(
            description="Instructions for submitting physical creative materials (print, static OOH, cinema). Present only for products requiring physical delivery outside the digital creative assignment flow. Buyer agents MUST validate url and email domains against the seller's known domains (from adagents.json) before submitting materials. Never auto-submit without human confirmation."
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> Product:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('format_ids',), ('format_options',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'Product requires at least one of these field groups: format_ids | format_options'
        )

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 acceptance_policy_profile_ids : AcceptancePolicyProfileIds | None
var allowed_actions : list[ProductAllowedAction] | None
var audience_activation : AudienceActivation | None
var audience_evidence : list[AudienceEvidence] | None
var audience_evidence_selections : list[AudienceEvidenceSelection] | None
var audio_distribution_types : list[AudioDistributionType] | None
var brief_relevance : str | None
var cancellation_policy : CancellationPolicy | None
var catalog_match : CatalogMatch | None
var catalog_types : list[CatalogType] | None
var channels : list[MediaChannel] | None
var collection_targeting_allowed : bool | None
var collections : list[CollectionSelector] | None
var conversion_tracking : ConversionTracking | None
var creative_policy : CreativePolicy | None
var data_provider_signals : list[DataProviderSignalSelector1 | DataProviderSignalSelector2 | DataProviderSignalSelector3] | None
var delivery_measurement : DeliveryMeasurement | None
var delivery_type : DeliveryType
var demographic_targeting : DemographicTargetingCapability | None
var description : str
var enforced_policies : list[str] | None
var exclusivity : Exclusivity | None
var execution_requirements : list[ProductExecutionRequirement1 | ProductExecutionRequirement2 | ProductExecutionRequirement3] | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var forecast : DeliveryForecast | None
var format_ids : list[FormatReferenceStructuredObject] | None
var format_options : list[ProductFormatDeclaration1 | ProductFormatDeclaration2 | ProductFormatDeclaration3 | ProductFormatDeclaration4 | ProductFormatDeclaration5 | ProductFormatDeclaration6 | ProductFormatDeclaration7 | ProductFormatDeclaration8 | ProductFormatDeclaration9 | ProductFormatDeclaration10 | ProductFormatDeclaration11 | ProductFormatDeclaration12 | ProductFormatDeclaration13 | ProductFormatDeclaration14 | ProductFormatDeclaration15 | ProductFormatDeclaration16] | None
var identity : ProductIdentity | None
var included_signals : list[SignalListing] | None
var installments : list[Installment] | None
var is_custom : bool | None
var list_applications : list[InventoryListApplication1 | InventoryListApplication2] | None
var material_submission : MaterialSubmission | None
var max_optimization_goals : int | None
var measurement_readiness : MeasurementReadiness | None
var measurement_terms : MeasurementTerms | None
var media_buy_support : ProductMediaBuySupport | None
var metric_optimization : MetricOptimization | None
var model_config
var name : str
var outcome_measurement : OutcomeMeasurement | None
var overlay_support : TargetingOverlaySupport | None
var performance_standards : list[PerformanceStandard] | None
var placements : list[Placement] | None
var pricing_options : list[CpmPricingOption | VcpmPricingOption | CpcPricingOption | CpcvPricingOption | CpvPricingOption | CppPricingOption | CpaPricingOption | RevenueSharePricingOption | FlatRatePricingOption | TimeBasedPricingOption]
var product_card : ProductCard | None
var product_card_detailed : ProductCardDetailed | None
var product_id : str
var property_targeting_allowed : bool | None
var publisher_properties : list[PublisherProperty85 | PublisherProperty86 | PublisherProperty87]
var reporting_capabilities : ReportingCapabilities
var signal_targeting_allowed : bool | None
var signal_targeting_options : list[ProductSignalTargetingOption] | None
var signal_targeting_rules : SignalTargetingRules | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var targeting_resolution : ProductTargetingResolution | None
var trusted_match : TrustedMatch | None
var vendor_metric_optimization : VendorMetricOptimization | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class ProductAllocation (**data: Any)
Expand source code
class ProductAllocation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    product_id: Annotated[
        str, Field(description='ID of the product (must reference a product in the products array)')
    ]
    allocation_percentage: Annotated[
        StrictFloat | None,
        Field(
            description='Exact percentage of total budget allocated to this product in a fixed proposal. Percentages across all allocations MUST sum to 100. Must be absent in a seller-optimized proposal.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    min_spend_target_percentage: Annotated[
        StrictFloat | None,
        Field(
            description='Soft minimum-spend target as a percentage of the executed total budget. Only valid in seller-optimized proposals, and sellers MUST NOT emit it unless they advertise media_buy.features.seller_optimized_min_spend_targets. The seller SHOULD attempt to reach it, but it is not a delivery guarantee. Minimum targets across allocations MUST sum to no more than 100.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    max_spend_percentage: Annotated[
        StrictFloat | None,
        Field(
            description='Hard maximum share of the executed total budget that this product may spend. Only valid in seller-optimized proposals, and sellers MUST NOT emit it unless they advertise media_buy.features.seller_optimized_package_budgets. Maximums across allocations MUST collectively permit 100 percent of the budget to be spent.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    pacing: Annotated[
        pacing_1.Pacing | None,
        Field(
            description='Recommended subordinate package pacing. On proposal execution this becomes pacing on the derived package and MUST NOT cause delivery to exceed aggregate proposal/media-buy pacing. On a committed proposal it is a firm delivery term. On a seller-optimized proposal, sellers MUST NOT emit it unless they advertise media_buy.features.seller_optimized_package_pacing.'
        ),
    ] = None
    pricing_option_id: Annotated[
        str | None,
        Field(
            description="Selected pricing option ID from the product's pricing_options array. Required when the containing proposal is committed so create_media_buy executes the exact disclosed commercial terms; optional on legacy draft proposals."
        ),
    ] = None
    rationale: Annotated[
        str | None,
        Field(description='Explanation of why this product and allocation are recommended'),
    ] = None
    sequence: Annotated[
        SchemaInt | None,
        Field(description='Optional ordering hint for multi-line-item plans (1-based)', ge=1),
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Categorical tags for this allocation (e.g., 'desktop', 'german', 'mobile') - useful for grouping/filtering allocations by dimension"
        ),
    ] = None
    start_time: Annotated[
        AwareDatetime | None,
        Field(
            description='Recommended flight start date/time for this allocation in ISO 8601 format. Allows publishers to propose per-flight scheduling within a proposal. When omitted, the allocation applies to the full campaign date range.'
        ),
    ] = None
    end_time: Annotated[
        AwareDatetime | None,
        Field(
            description='Recommended flight end date/time for this allocation in ISO 8601 format. Allows publishers to propose per-flight scheduling within a proposal. When omitted, the allocation applies to the full campaign date range.'
        ),
    ] = None
    daypart_targets: Annotated[
        list[daypart_target.DaypartTarget] | None,
        Field(
            description="Recommended time windows for this allocation in spot-plan proposals. Each entry's timezone defaults to inventory_local when omitted, and entries MAY use different clocks.",
            min_length=1,
        ),
    ] = None
    forecast: Annotated[
        delivery_forecast.DeliveryForecast | None,
        Field(description='Forecasted delivery metrics for this allocation'),
    ] = None
    ext: ext_1.ExtensionObject | 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 allocation_percentage : float | None
var daypart_targets : list[DaypartTarget] | None
var end_time : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var forecast : DeliveryForecast | None
var max_spend_percentage : float | None
var min_spend_target_percentage : float | None
var model_config
var pacing : Pacing | None
var pricing_option_id : str | None
var product_id : str
var rationale : str | None
var sequence : int | None
var start_time : pydantic.types.AwareDatetime | None
var tags : list[str] | None

Inherited members

class ProductAllowedAction (**data: Any)
Expand source code
class ProductAllowedAction(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    action: Annotated[
        media_buy_available_action_id.MediaBuyAvailableActionId,
        Field(
            description='The action identifier. Accepts every legacy valid_actions value plus structured-only actions such as update_media_buy_frequency_cap.'
        ),
    ]
    modes: Annotated[
        list[media_buy_action_mode.MediaBuyActionMode],
        Field(
            description='Modes available for this action on this product. A product may declare multiple modes (for example `self_serve` within tolerances, escalating to `requires_approval` outside) — the buy-side `available_actions[<action>].mode` resolves to the singular mode in effect at mutation time. SDKs that see multiple modes MUST NOT assume which one will fire; they must read the resolved `mode` on the buy.',
            min_length=1,
        ),
    ]
    allowed_statuses: Annotated[
        list[media_buy_status.MediaBuyStatus] | None,
        Field(
            description='Media buy statuses in which this action is permitted. When absent, the action is permitted in all non-terminal statuses (`pending_creatives`, `pending_start`, `active`, `paused`).',
            min_length=1,
        ),
    ] = None
    sla: Annotated[
        sla_window.SlaWindow | None,
        Field(
            description='Optional SLA commitment for this action on this product. Absence means no commitment.'
        ),
    ] = None
    constraints: Annotated[
        change_term_constraints.MediaBuyChangeTermConstraints | None,
        Field(
            description='Optional advisory machine-readable bounds buyers can use during product selection. The proposal must restate any binding bounds in commercial_terms.change_terms[].constraints.'
        ),
    ] = None
    terms_ref: Annotated[
        str | None,
        Field(
            description='Optional advisory pointer to published commercial terms governing this product action. It is not a proposal change-term identity and never grants a binding change right; a proposal materializes binding rights under commercial_terms.change_terms[].term_id.'
        ),
    ] = 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 action : MediaBuyValidAction | Literal['update_media_buy_frequency_cap']
var allowed_statuses : list[MediaBuyStatus] | None
var constraints : MediaBuyChangeTermConstraints1 | MediaBuyChangeTermConstraints2 | MediaBuyChangeTermConstraints3 | MediaBuyChangeTermConstraints4 | None
var model_config
var modes : list[MediaBuyActionMode]
var sla : SlaWindow | None
var terms_ref : str | None

Inherited members

class ProductAudienceEvidenceRequirements (**data: Any)
Expand source code
class ProductAudienceEvidenceRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    requirement_mode: RequirementMode
    evidence_presence: EvidencePresence
    accepted_methodologies: Annotated[
        list[audience_evidence_methodology.AudienceEvidenceMethodology] | None, Field(min_length=1)
    ] = None
    excluded_methodologies: Annotated[
        list[audience_evidence_methodology.AudienceEvidenceMethodology] | None, Field(min_length=1)
    ] = None
    accepted_evidence_types: Annotated[list[AcceptedEvidenceType] | None, Field(min_length=1)] = (
        None
    )
    accepted_providers: Annotated[list[brand_key.BrandKey] | None, Field(min_length=1)] = None
    excluded_providers: Annotated[list[brand_key.BrandKey] | None, Field(min_length=1)] = None
    accepted_subject_types: Annotated[
        list[audience_subject_type.AudienceSubjectType] | None, Field(min_length=1)
    ] = None
    accepted_resolution_methods: Annotated[
        list[audience_resolution_method.AudienceResolutionMethod] | None, Field(min_length=1)
    ] = None
    minimum_confidence: Annotated[StrictFloat | None, Field(ge=0.0, le=1.0)] = None
    maximum_age: MaximumAge | None = None
    methodology_documentation_required: StrictBool | None = False
    independent_attestation_required: StrictBool | None = False
    accepted_attestation_issuers: Annotated[
        list[AcceptedAttestationIssuers] | None, Field(min_length=1)
    ] = None
    accepted_attestation_claim_types: Annotated[list[AnyUrl] | None, Field(min_length=1)] = None
    ext: ext_1.ExtensionObject | 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 accepted_attestation_claim_types : list[pydantic.networks.AnyUrl] | None
var accepted_attestation_issuers : list[AcceptedAttestationIssuers1 | AcceptedAttestationIssuers2 | AcceptedAttestationIssuers3] | None
var accepted_evidence_types : list[AcceptedEvidenceType] | None
var accepted_methodologies : list[AudienceEvidenceMethodology] | None
var accepted_providers : list[BrandKey] | None
var accepted_resolution_methods : list[AudienceResolutionMethod] | None
var accepted_subject_types : list[AudienceSubjectType] | None
var evidence_presence : EvidencePresence
var excluded_methodologies : list[AudienceEvidenceMethodology] | None
var excluded_providers : list[BrandKey] | None
var ext : ExtensionObject | None
var independent_attestation_required : bool | None
var maximum_age : MaximumAge | None
var methodology_documentation_required : bool | None
var minimum_confidence : float | None
var model_config
var requirement_mode : RequirementMode

Inherited members

class ProductCard (**data: Any)
Expand source code
class ProductCard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    image: Annotated[
        image_asset.ImageAsset | None,
        Field(
            description='Hero image for the card. Recommended ~300x400 (4:3 portrait) for the standard card layout; receivers may scale.'
        ),
    ] = None
    title: Annotated[
        str | None, Field(description='Card title (typically the product name).', max_length=60)
    ] = None
    description: Annotated[
        str | None,
        Field(description='Short descriptive blurb shown below the title.', max_length=200),
    ] = None
    price_label: Annotated[
        str | None,
        Field(
            description="Formatted price or pricing summary (e.g., 'From $5 CPM', 'Auction floor $0.50 CPC'). Free-text — receivers render verbatim.",
            max_length=30,
        ),
    ] = None
    cta_label: Annotated[
        str | None,
        Field(
            description="Call-to-action button label (e.g., 'View details', 'Get proposal').",
            max_length=25,
        ),
    ] = 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 cta_label : str | None
var description : str | None
var image : ImageAsset | None
var model_config
var price_label : str | None
var title : str | None

Inherited members

class ProductCardDetailed (**data: Any)
Expand source code
class ProductCardDetailed(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    hero_image: Annotated[
        image_asset.ImageAsset | None,
        Field(description='Primary hero image at the top of the detailed view.'),
    ] = None
    carousel_images: Annotated[
        list[image_asset.ImageAsset] | None,
        Field(description='Additional images for a swipeable carousel below the hero.'),
    ] = None
    title: Annotated[str | None, Field(description='Page title (typically the product name).')] = (
        None
    )
    description: Annotated[
        str | None,
        Field(
            description='Full descriptive copy. Markdown allowed in client renderers that support it; otherwise treat as plain text.'
        ),
    ] = None
    specifications: Annotated[
        list[Specification] | None,
        Field(
            description="Structured key/value specifications (e.g., 'Aspect ratio: 9:16', 'Duration: 30s'). Each item is a labeled fact about the product."
        ),
    ] = None
    price_label: Annotated[str | None, Field(description='Formatted price or pricing summary.')] = (
        None
    )
    cta_label: Annotated[str | None, Field(description='Call-to-action button label.')] = None
    reference_assets: Annotated[
        list[product_card_reference_asset.ProductCardReferenceAsset] | None,
        Field(
            description='Typed seller collateral for buyer planning — coverage maps, sample renders, environment photos, media kits. Distinct from hero_image/carousel_images, which are display-oriented.'
        ),
    ] = 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 carousel_images : list[ImageAsset] | None
var cta_label : str | None
var description : str | None
var hero_image : ImageAsset | None
var model_config
var price_label : str | None
var reference_assets : list[ProductCardReferenceAsset] | None
var specifications : list[Specification] | None
var title : str | None

Inherited members

class ProductCardReferenceAsset (**data: Any)
Expand source code
class ProductCardReferenceAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    role: Annotated[
        Role,
        Field(
            description='Semantic role of this asset. coverage_map: geographic or audience reach visualization; sample_render: mockup of ad placement in context; environment_photo: photo of the physical or digital environment; media_kit: downloadable media kit or spec sheet; logo: seller or property logo; other: seller-defined role (provide role_label).'
        ),
    ]
    role_label: Annotated[
        str | None,
        Field(
            description="Human-readable label for the asset role. Required when role is 'other'; optional otherwise."
        ),
    ] = None
    asset: Annotated[
        image_asset.ImageAsset
        | video_asset.VideoAsset
        | markdown_asset.MarkdownAsset
        | url_asset.UrlAsset,
        Field(
            description='The asset payload, discriminated on asset_type (image, video, markdown, url).'
        ),
    ]
    description: Annotated[
        str | None, Field(description='Optional human-readable context about this asset.')
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset : ImageAsset | VideoAsset | MarkdownAsset | UrlAsset
var description : str | None
var model_config
var role : Role
var role_label : str | None

Inherited members

class ProductChangeMap (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class ProductChangeMap(RootModel[dict[Annotated[str, StringConstraints(min_length=1)], ProductChangeMap1]]):
    root: Annotated[
        dict[Annotated[str, StringConstraints(min_length=1)], ProductChangeMap1],
        Field(
            description='Product IDs mapped to deterministic membership actions. Object keys are product identifiers, so contradictory actions for one product cannot be represented.',
            min_length=1,
            title='Product Change Map',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[dict[Annotated[str, StringConstraints], ProductChangeMap1]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : dict[str, ProductChangeMap1]
class ProductChangeMap1 (*args, **kwds)
Expand source code
class ProductChangeMap1(StrEnum):
    include = 'include'
    omit = 'omit'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var include
var omit
class ProductDoohPlacementAttributes (**data: Any)
Expand source code
class ProductDoohPlacementAttributes(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    slot_duration_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Scheduled duration of one ad slot in seconds. This is an inventory fact used for loop and share calculations, not the creative-duration contract.',
            ge=1,
        ),
    ] = None
    loop_duration_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Duration of the full ad loop rotation in seconds and the canonical source for loop duration.',
            ge=1,
        ),
    ] = None
    screen_resolution: ProductDoohScreenResolution | None = None
    motion: Annotated[
        dooh_motion_type.DoohMotionType | None,
        Field(
            description='Physical motion capability of a visual DOOH screen, not an accepted-format declaration. Omit for audio-only placements.'
        ),
    ] = 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 loop_duration_seconds : int | None
var model_config
var motion : DoohMotionType | None
var screen_resolution : ProductDoohScreenResolution | None
var slot_duration_seconds : int | None

Inherited members

class ProductDoohScreenResolution (**data: Any)
Expand source code
class ProductDoohScreenResolution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    width: Annotated[SchemaInt, Field(description='Screen width in pixels.', ge=1)]
    height: Annotated[SchemaInt, Field(description='Screen height in pixels.', ge=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 height : int
var model_config
var width : int

Inherited members

class ProductExecutionRequirement1 (**data: Any)
Expand source code
class ProductExecutionRequirement1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['event_source'] = 'event_source'
    event_types: Annotated[
        list[event_type.EventType] | None,
        Field(
            description='Event types that satisfy the requirement (any-of): the satisfying `event_sources[]` entry MUST use one of these `event_type` values. Omit when any event type satisfies it.',
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 event_types : list[EventType] | None
var ext : ExtensionObject | None
var kind : Literal['event_source']
var model_config

Inherited members

class ProductExecutionRequirement2 (**data: Any)
Expand source code
class ProductExecutionRequirement2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['catalog'] = 'catalog'
    catalog_types: Annotated[
        list[catalog_type.CatalogType],
        Field(
            description='Catalog types that satisfy the requirement (any-of). One catalog of any listed type satisfies it.',
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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 catalog_types : list[CatalogType]
var ext : ExtensionObject | None
var kind : Literal['adcp.types.domains.core.catalog']
var model_config

Inherited members

class ProductExecutionRequirement3 (**data: Any)
Expand source code
class ProductExecutionRequirement3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['downstream_connection'] = 'downstream_connection'
    connection: Annotated[
        Connection,
        Field(
            description='The required connection. Account-independent: `status` is omitted or `unknown`; `resource_ref`, `connection_id`, and `expires_at` MUST be omitted; `required_for`, when present, includes `create_media_buy`.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 connection : Connection
var ext : ExtensionObject | None
var kind : Literal['downstream_connection']
var model_config

Inherited members

class ProductFilters (**data: Any)
Expand source code
class ProductFilters(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    delivery_type: delivery_type_1.DeliveryType | None = None
    exclusivity: Annotated[
        exclusivity_1.Exclusivity | None,
        Field(
            description="Filter by exclusivity level. Returns products matching the specified exclusivity (e.g., 'exclusive' returns only sole-sponsorship products)."
        ),
    ] = None
    is_fixed_price: Annotated[
        StrictBool | None,
        Field(
            description='Legacy filter for fixed versus auction pricing availability. true returns options with fixed_price; false returns auction options whose price is established through bid_price. Contingent options such as revenue_share match neither value and MUST be omitted whenever this filter is present. Use pricing_structures to discover contingent pricing. Products with both fixed and auction options match both true and false, but sellers MUST return only entries matching the requested structure.'
        ),
    ] = None
    pricing_structures: Annotated[
        list[pricing_structure.PricingStructure] | None,
        Field(
            description='Filter by how the payable price is determined. fixed selects options with fixed_price, auction selects options established through bid_price, and contingent selects options calculated from a measured business outcome after delivery (currently revenue_share). Products match when at least one pricing option has a requested structure. Sellers MUST return only matching pricing_options entries. When combined with is_fixed_price, both filters apply and the returned entries must satisfy both.',
            min_length=1,
        ),
    ] = None
    pricing_currencies: Annotated[
        list[PricingCurrency] | None,
        Field(
            description='Filter by currencies the buyer can use for the media product transaction, using ISO 4217 currency codes. Products match when they offer at least one product-level pricing_options entry in one of the requested currencies and any seller-applied or otherwise mandatory product-scoped signal charges are satisfiable in one of those currencies or have no incremental price. Mandatory custom signal pricing without currency is not satisfiable for this filter unless the seller can truthfully treat it as having no incremental price. Sellers MUST return only product pricing_options entries whose currency is in this list so buyers can select deterministically from discovery. This filter does not require pruning optional signal or vendor add-on pricing; buyers should avoid optional add-ons priced only in unsupported currencies.',
            min_length=1,
        ),
    ] = None
    format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Filter by legacy named-format references. Use `format_kinds` or `format_option_refs`.',
            min_length=1,
        ),
    ] = None
    format_kinds: Annotated[
        list[str] | None,
        Field(
            description='Filter to products accepting any of these canonical format kinds.',
            min_length=1,
        ),
    ] = None
    format_option_refs: Annotated[
        list[format_option_ref.FormatOptionReference] | None,
        Field(
            description='Filter to products accepting any of these exact publisher- or product-scoped canonical format options.',
            min_length=1,
        ),
    ] = None
    standard_formats_only: Annotated[
        StrictBool | None, Field(description='Only return products accepting IAB standard formats')
    ] = None
    min_exposures: Annotated[
        SchemaInt | None,
        Field(description='Minimum exposures/impressions needed for measurement validity', ge=1),
    ] = None
    start_date: Annotated[
        date | None,
        Field(
            description='Campaign start date (ISO 8601 date format: YYYY-MM-DD) for availability checks'
        ),
    ] = None
    end_date: Annotated[
        date | None,
        Field(
            description='Campaign end date (ISO 8601 date format: YYYY-MM-DD) for availability checks'
        ),
    ] = None
    budget_range: Annotated[
        BudgetRange | None, Field(description='Budget range to filter appropriate products')
    ] = None
    countries: Annotated[
        list[Country] | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy coverage filter. On compact discovery tasks use criteria.offer_filters.countries. Return products whose inventory covers at least one requested area; this does not impose delivery targeting or require selectable targeting support. Retained get_products handlers MUST preserve the original coverage predicate.',
            min_length=1,
        ),
    ] = None
    regions: Annotated[
        list[Region] | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy coverage filter. On compact discovery tasks use criteria.offer_filters.regions. Return products whose inventory covers at least one requested area; this does not impose delivery targeting or require selectable targeting support. Retained get_products handlers MUST preserve the original coverage predicate.',
            min_length=1,
        ),
    ] = None
    metros: Annotated[
        list[Metro] | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy coverage filter. On compact discovery tasks use criteria.offer_filters.metros. Return products whose inventory covers at least one requested area; this does not impose delivery targeting or require selectable targeting support. Retained get_products handlers MUST preserve the original coverage predicate.',
            min_length=1,
        ),
    ] = None
    channels: Annotated[
        list[channels_1.MediaChannel] | None,
        Field(
            description="Filter by advertising channels (e.g., ['display', 'ctv', 'dooh'])",
            min_length=1,
        ),
    ] = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None,
        Field(
            description='Filter product metadata by declared video placement types, using IAB Tech Lab/OpenRTB 2.6 video.plcmt definitions with AdCP-native names. A product matches when its declared array intersects the requested array. This is discovery classification only and does not promise delivery exclusively on a requested type; buyers needing exact placement inventory use targeting_overlay.placement_selection against targetable placements. This filter has set semantics for wholesale feed canonicalization.',
            min_length=1,
        ),
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None,
        Field(
            description='Filter product metadata by declared audio distribution types, using IAB Tech Lab/OpenRTB 2.6 audio.feed definitions with AdCP-native names. A product matches when its declared array intersects the requested array. This is discovery classification only and does not promise delivery exclusively on a requested type. This filter has set semantics for wholesale feed canonicalization.',
            min_length=1,
        ),
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None,
        Field(
            description='Filter retail-media product metadata by declared sponsored-placement types (sponsored search, sponsored display, or sponsored native). A product matches when its declared array intersects the requested array. This is discovery classification only and does not promise delivery exclusively on a requested type. This filter has set semantics for wholesale feed canonicalization.',
            min_length=1,
        ),
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None,
        Field(
            description='Filter social-product metadata by declared placement surfaces (feed, stories, short_video, explore, or search). A product matches when its declared array intersects the requested array. This is discovery classification only and does not promise delivery exclusively on a requested surface; buyers needing an exact public placement use targeting_overlay.placement_selection. This filter has set semantics for wholesale feed canonicalization.',
            min_length=1,
        ),
    ] = None
    required_axe_integrations: Annotated[
        list[AnyUrl] | None,
        Field(
            deprecated=True,
            description='Deprecated: Use trusted_match filter instead. Filter to products executable through specific agentic ad exchanges. URLs are canonical identifiers.',
            min_length=1,
        ),
    ] = None
    trusted_match: Annotated[
        TrustedMatch | None,
        Field(
            description='Filter products by Trusted Match Protocol capabilities. Only products with matching TMP support are returned.'
        ),
    ] = None
    audience_activation_methods: Annotated[
        list[
            AudienceActivationMethods
            | AudienceActivationMethods1
            | AudienceActivationMethods2
            | AudienceActivationMethods3
            | AudienceActivationMethods4
            | AudienceActivationMethods5
        ]
        | None,
        Field(
            description="Filter to products whose audience_activation.methods matches at least one requested entry (OR across entries). Within an entry every specified field must match (AND); omitted optional fields are wildcards; directions matches on non-empty intersection, and a method that omits directions matches any requested directions; vendor matches on domain, plus brand_id when specified. Fields inapplicable to the requested pattern (e.g. transport on a clean_room entry) make that entry unsatisfiable. Sellers MUST exclude products with no audience_activation declaration when this filter is present; exclusions MAY be reported via filter_diagnostics.excluded_by. Experimental: part of the media_buy.audience_activation surface — buyers SHOULD check the seller's experimental_features before filtering on it; sellers that do not list the feature ignore this filter.",
            min_length=1,
        ),
    ] = None
    required_features: Annotated[
        media_buy_features.MediaBuyFeatures | None,
        Field(
            description='Filter to products from sellers supporting specific protocol features. Only features set to true are used for filtering.'
        ),
    ] = None
    required_geo_targeting: Annotated[
        list[RequiredGeoTargetingItem] | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use get_products.required_overlay_support, which is product-scoped and applies consistently to geographic and non-geographic targeting dimensions.',
            min_length=1,
        ),
    ] = None
    signal_targeting: Annotated[
        list[SignalTargetingItem] | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy signal-option eligibility filter. Retained get_products handlers MUST preserve the signal identity, value predicate, and requested include/exclude capability. This does not activate delivery targeting. Native buyers use criteria.targeting_overlay.signal_targeting_groups only for concrete delivery selections, preserving exclusion through group operators; copying targeting_mode into targeting_overlay.signal_targeting does not preserve it.',
            min_length=1,
        ),
    ] = None
    postal_areas: Annotated[
        list[postal_area.PostalArea] | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy coverage filter. On compact discovery tasks use criteria.offer_filters.postal_areas. Return products whose inventory covers at least one requested area; this does not impose delivery targeting or require selectable targeting support. Retained get_products handlers MUST preserve the original coverage predicate.',
            min_length=1,
        ),
    ] = None
    geo_proximity: Annotated[
        list[GeoProximityItem] | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy coverage filter. On compact discovery tasks use criteria.offer_filters.geo_proximity. Return products whose inventory covers at least one requested area; this does not impose delivery targeting or require selectable targeting support. Retained get_products handlers MUST preserve the original coverage predicate.',
            min_length=1,
        ),
    ] = None
    required_performance_standards: Annotated[
        list[performance_standard.PerformanceStandard] | None,
        Field(
            description="Filter to products that can meet the buyer's performance standard requirements. Each entry specifies a metric, minimum threshold, and optionally a required vendor and standard. Products that cannot meet these thresholds or do not support the specified vendors are excluded. Use this to tell the seller upfront: 'I need DoubleVerify for viewability at 70% MRC.'",
            min_length=1,
        ),
    ] = None
    required_metrics: Annotated[
        list[available_metric.AvailableMetric] | None,
        Field(
            description="Filter to products whose `reporting_capabilities.available_metrics` is a superset of these metrics — i.e., products that commit to reporting all listed metrics in delivery responses. Use this for capability-level discovery (e.g., 'I need products that report `completed_views` for a CTV CPCV buy'); guarantee-level requirements with thresholds belong in `required_performance_standards` and `measurement_terms`. Sellers MUST silently exclude products that cannot meet this list (filter-not-fail; do not return an error). Under the container-subsumption rule in `enums/available-metric.json`, `viewability` satisfies numeric leaves such as `viewable_rate`; structured distributions require explicit `viewed_seconds_percentiles` or `viewed_seconds_histogram` declarations. The product's declared `available_metrics` becomes the binding reporting contract carried into the resulting media buy — the same metric vocabulary is used to compute `missing_metrics` on `get_media_buy_delivery`.",
            examples=[
                ['completed_views'],
                ['completed_views', 'completion_rate'],
                ['impressions', 'spend', 'engagements'],
            ],
            min_length=1,
        ),
    ] = None
    required_vendor_metrics: Annotated[
        list[RequiredVendorMetric] | None,
        Field(
            description="Filter to products whose `reporting_capabilities.vendor_metrics` matches these criteria. Each entry pins a `vendor` (matches any metric from that vendor), a `metric_id` (matches the metric across any vendor that uses that identifier), or both (specific vendor's specific metric). A product matches if its declared `vendor_metrics` covers ALL listed entries (AND across entries; pins within an entry are conjunctive). Cross-vendor discovery (e.g., 'I need attention measurement from any vendor that does it') is the buyer agent's responsibility — the agent resolves which vendors offer a category via the vendors' `brand.json` records, then enumerates them as filter entries. AdCP does not carry vendor-side metric metadata (category, methodology, standard alignment) in the filter surface; that lives at the vendor and is queried out-of-band. Sellers MUST silently exclude non-matching products (filter-not-fail; do not return an error) — same convention as the other `required_*` filters.",
            examples=[
                [{'vendor': {'domain': 'attentionvendor.example'}}],
                [
                    {
                        'vendor': {'domain': 'panelmeasurement.example'},
                        'metric_id': 'demographic_reach',
                    }
                ],
                [
                    {'vendor': {'domain': 'attentionvendor.example'}},
                    {'vendor': {'domain': 'secondattentionvendor.example'}},
                ],
            ],
            min_length=1,
        ),
    ] = None
    keywords: Annotated[
        list[Keyword] | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy product eligibility filter. Retained get_products handlers MUST preserve the requested keyword eligibility and match_type (default broad). This is not an instruction to add package keyword targeting. Native buyers use criteria.targeting_overlay.keyword_targets only when they intend a delivery constraint, or criteria.required_overlay_support.keyword_targets for future selectability.',
            min_length=1,
        ),
    ] = None
    audience_evidence_requirements: Annotated[
        audience_evidence_requirements_1.AudienceEvidenceRequirements | None,
        Field(
            description='Buyer policy for evaluating Product.audience_evidence. In required mode, sellers MUST apply the evidence_presence and admissibility semantics and exclude non-matching products; they MUST NOT ignore an unsupported hard requirement. In preferred mode, sellers use matches for ranking and explain the evidence selected. Buyers SHOULD inspect media_buy.audience_evidence capabilities before sending this object.'
        ),
    ] = None
    ext: Annotated[
        ext_1.ExtensionObject | None,
        Field(
            description='Vendor-namespaced extension parameters for seller-specific filter criteria not covered by standard fields. Keys MUST be namespaced under a vendor or platform key (e.g., ext.gam, ext.platform_x). Sellers MUST treat all values as untrusted buyer input; do not interpolate into LLM prompts, SQL queries, or system commands without sanitization. Persistent use of an extension key across multiple buyers is a signal to propose standardization.'
        ),
    ] = 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 audience_activation_methods : list[AudienceActivationMethods | AudienceActivationMethods1 | AudienceActivationMethods2 | AudienceActivationMethods3 | AudienceActivationMethods4 | AudienceActivationMethods5] | None
var audience_evidence_requirements : AudienceEvidenceRequirements | None
var audio_distribution_types : list[AudioDistributionType] | None
var budget_range : BudgetRange | None
var channels : list[MediaChannel] | None
var countries : list[Country] | None
var delivery_type : DeliveryType | None
var end_date : datetime.date | None
var exclusivity : Exclusivity | None
var ext : ExtensionObject | None
var format_ids : list[FormatReferenceStructuredObject] | None
var format_kinds : list[str] | None
var format_option_refs : list[FormatOptionReference1 | FormatOptionReference2] | None
var geo_proximity : list[GeoProximityItem] | None
var is_fixed_price : bool | None
var keywords : list[Keyword] | None
var metros : list[Metro] | None
var min_exposures : int | None
var model_config
var postal_areas : list[PostalArea] | None
var pricing_currencies : list[PricingCurrency] | None
var pricing_structures : list[PricingStructure] | None
var regions : list[Region] | None
var required_axe_integrations : list[pydantic.networks.AnyUrl] | None
var required_features : MediaBuyFeatures | None
var required_geo_targeting : list[RequiredGeoTargetingItem] | None
var required_metrics : list[AvailableMetric] | None
var required_performance_standards : list[PerformanceStandard] | None
var required_vendor_metrics : list[RequiredVendorMetric] | None
var signal_targeting : list[SignalTargetingItem5 | SignalTargetingItem6 | SignalTargetingItem7] | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var standard_formats_only : bool | None
var start_date : datetime.date | None
var trusted_match : TrustedMatch | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class ProductFormatDeclaration1 (**data: Any)
Expand source code
class ProductFormatDeclaration1(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image'] = 'image'
    params: image.CanonicalFormatImage

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImage
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration10 (**data: Any)
Expand source code
class ProductFormatDeclaration10(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['sponsored_placement'] = 'sponsored_placement'
    params: sponsored_placement.CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['sponsored_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration11 (**data: Any)
Expand source code
class ProductFormatDeclaration11(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['native_in_feed'] = 'native_in_feed'
    params: native_in_feed.CanonicalFormatNativeInFeed

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['native_in_feed']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatNativeInFeed
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration12 (**data: Any)
Expand source code
class ProductFormatDeclaration12(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['responsive_creative'] = 'responsive_creative'
    params: responsive_creative.CanonicalFormatResponsiveCreative

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['responsive_creative']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatResponsiveCreative
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration13 (**data: Any)
Expand source code
class ProductFormatDeclaration13(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['agent_placement'] = 'agent_placement'
    params: agent_placement.CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['agent_placement']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration14 (**data: Any)
Expand source code
class ProductFormatDeclaration14(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['seller_rendered_stateful_display'] = 'seller_rendered_stateful_display'
    params: seller_rendered_stateful_display.CanonicalFormatSellerRenderedStatefulDisplay

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['seller_rendered_stateful_display']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatSellerRenderedStatefulDisplay
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration15 (**data: Any)
Expand source code
class ProductFormatDeclaration15(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['coordinated_placements'] = 'coordinated_placements'
    params: coordinated_placements.CanonicalFormatCoordinatedPlacements

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['coordinated_placements']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatCoordinatedPlacements
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration16 (**data: Any)
Expand source code
class ProductFormatDeclaration16(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['custom'] = 'custom'
    params: Annotated[
        dict[str, Any],
        Field(
            description="Custom shape's params. Validated against the schema fetched from `format_schema.uri` at the cached `format_schema.digest`."
        ),
    ]

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['custom']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : dict[str, typing.Any]
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration2 (**data: Any)
Expand source code
class ProductFormatDeclaration2(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['html5'] = 'html5'
    params: html5.CanonicalFormatHtml5Banner

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['html5']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHtml5Banner
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration3 (**data: Any)
Expand source code
class ProductFormatDeclaration3(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['display_tag'] = 'display_tag'
    params: display_tag.CanonicalFormatDisplayTag

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['display_tag']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDisplayTag
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration4 (**data: Any)
Expand source code
class ProductFormatDeclaration4(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['image_carousel'] = 'image_carousel'
    params: image_carousel.CanonicalFormatImageCarousel

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['image_carousel']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatImageCarousel
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration5 (**data: Any)
Expand source code
class ProductFormatDeclaration5(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_hosted'] = 'video_hosted'
    params: video_hosted.CanonicalFormatHostedVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration6 (**data: Any)
Expand source code
class ProductFormatDeclaration6(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['video_vast'] = 'video_vast'
    params: video_vast.CanonicalFormatVastVideo

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['video_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastVideo
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration7 (**data: Any)
Expand source code
class ProductFormatDeclaration7(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_hosted'] = 'audio_hosted'
    params: audio_hosted.CanonicalFormatHostedAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_hosted']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatHostedAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration8 (**data: Any)
Expand source code
class ProductFormatDeclaration8(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_vast'] = 'audio_vast'
    params: audio_vast.CanonicalFormatVastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_vast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatVastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductFormatDeclaration9 (**data: Any)
Expand source code
class ProductFormatDeclaration9(AdCPBaseModel):
    format_option_id: Annotated[
        str | None,
        Field(
            description="Stable identifier for this declaration within its namespace. REQUIRED when a product contains multiple declarations with the same format_kind and SHOULD be set on every entry. Publisher-backed options pair it with publisher_domain; product-local options omit publisher_domain. When a single declaration has a unique format_kind and no ID, buyers author canonically with format_kind plus params; they MUST NOT fall back to deprecated format_ids merely because this optional ID is absent. Examples: 'display_image_300x250', 'responsive_search', 'daily_pulse_homepage_image'."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Namespace for `format_option_id` when this declaration references or narrows a publisher-declared format option from that publisher's adagents.json top-level `formats[]`. Product-local options omit this field and are selected by `format_option_id` within the target product.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    tracker_execution_contract: Annotated[
        tracker_execution_contract_1.TrackerExecutionContract | None,
        Field(
            description='Seller- or publisher-authored commitment describing which first-class manifest trackers the selected format option accepts and initiates in production. The seller-returned Product declaration is binding; publisher and placement declarations are upstream inputs that the seller resolves into that effective contract. Presence requires a stable format_option_id. Creative-agent capability projections, transformer inputs, and deprecated canonical_parameters MUST reject this seller-authority field rather than copying it.'
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[macro_resolution_capability.MacroProcessingCapability] | None,
        Field(
            description='Binding format-option processing capabilities for exact macro dialect identities, semantics, operations, actors, contexts, and encodings. Absence means undeclared, not supported on the opt-in declared-token path. Seller-wide capabilities are only a ceiling. This field does not claim that a buyer tracker asset is honored or fired.',
            min_length=1,
        ),
    ] = None
    technical_requirements_complete: Annotated[
        StrictBool | None,
        Field(
            description='Completeness assertion for technical creative acceptance constraints in this declaration. When true, the declaring party asserts that every technical constraint within its authority is expressed by this declaration (including fetched custom-format and platform-extension schemas), and every omitted technical field means no constraint at that layer. A creative that satisfies the complete effective technical contract MUST NOT later be rejected for an undisclosed technical constraint. When false or absent, omitted technical constraints are undeclared: consumers MUST NOT interpret omission as support, no constraint, or a prose/default value. The effective product/placement contract is complete only when every applicable product, publisher, and placement declaration asserts true. This assertion is limited to technical acceptance; it does not waive policy, legal, security, malware, transport/fetch, corrupted-content, or materially misdeclared-asset checks. Creative size fields ending in `_kb` use exactly 1,000 bytes per KB and fields ending in `_mb` use exactly 1,000,000 bytes per MB.'
        ),
    ] = None
    display_name: Annotated[
        str | None,
        Field(
            description="Optional seller-controlled human-readable label for this format declaration. Used by buyer dashboards, catalog UIs, and reporting surfaces to show a seller's own naming ('Homepage Takeover', 'Branded Canvas', 'Reels Premium Video') rather than the raw `format_kind` or `format_option_id`. Has no machine semantics — buyer agents route on `format_kind` and `format_option_id`; `display_name` is purely for human presentation. Freeform; no enumeration. Sellers SHOULD keep it stable once published to avoid dashboard churn."
        ),
    ] = None
    sample_render_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional public HTTPS page where a human can inspect a sample render of this declaration using assets chosen by the party publishing the enclosing declaration. Consumers MUST identify that source correctly: publisher or community mirror for `adagents.json` `formats[]`, seller for product or inline-placement declarations, and creative agent for `creative.supported_formats`. Informational only: this is not a renderer endpoint, buyer-asset preview, validation result, creative approval, proof of publisher acceptance, or guarantee of live delivery. Declaring parties SHOULD keep the URL stable while the declaration is active.'
        ),
    ] = None
    applies_to_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Optional subset of the parent product's `channels` to which this declaration applies. When omitted, the declaration applies to ALL channels declared on the product. Lets a multi-channel product (e.g., `channels: ['display', 'video']`) carry distinct format_options per channel — `format_options: [{format_kind: 'image', applies_to_channels: ['display']}, {format_kind: 'video_hosted', applies_to_channels: ['video']}]`. Buyers ship channel-appropriate manifests per `applies_to_channels`."
        ),
    ] = None
    seller_preference: Annotated[
        SellerPreference | None,
        Field(
            description="Optional soft routing hint *within* a product's accepted set of formats — NOT an enforcement axis. `preferred` — seller actively recommends this format (often because of measurement, viewability, or render-quality differences); `accepted` — supported on equal footing with other format_options (default when omitted); `discouraged` — supported but suboptimal (e.g., legacy 3p-tag where the seller would prefer html5 for OM-SDK coverage). Buyer agents picking between format_options SHOULD respect seller preferences when their own constraints don't override.\n\n**Not an enforcement axis (normative).** `seller_preference` does NOT carry the meaning of 'this format won't work / required-only'. That case is structural: `format_options[]` IS the closed set of accepted formats; anything outside the list is rejected at `create_media_buy` regardless of preference. A seller that accepts only one format lists exactly that one entry — the structural fact does the enforcement work, no enum value needed. There is intentionally no `required` value; preference is bounded to *ranking within the already-accepted set*, not gating into it."
        ),
    ] = None
    locale_policy: Annotated[
        creative_locale_policy.CreativeLocalePolicy | None,
        Field(
            description='Optional seller-enforced creative-locale constraint for this format option. This is product/placement eligibility, not a new format kind or synthetic locale-specific format ID. Because legacy format_ids cannot preserve this constraint, declarations carrying locale_policy MUST set canonical_formats_only to true and MUST NOT carry v1_format_ref.'
        ),
    ] = None
    canonical_formats_only: Annotated[
        StrictBool | None,
        Field(
            description='When true, this format declaration has no clean v1 projection and SDKs MUST NOT synthesize a v1 `format_id` for it. Buyers reading the product on the v1 wire path see this declaration absent from `format_ids`; only v2-aware buyers (reading `format_options`) discover it. Set explicitly for `format_kind: "custom"` declarations (no canonical exists in v1 to project onto) and for declarations whose canonical/parameter shape cannot round-trip through a v1 named format without semantic loss. The protocol does NOT mint synthetic v1 format_ids for unmappable declarations — the alternative (an `aao-synth/*` namespace populated automatically) was considered and rejected because adopters would index on synthetic IDs that have no stable identity. Producers SHOULD set `canonical_formats_only: true` rather than omit the declaration from `format_options` — explicit v2-only is more useful than silent absence.'
        ),
    ] = False
    experimental: Annotated[
        StrictBool | None,
        Field(
            description="When true, this seller's specific canonical declaration may not work as declared even if the underlying canonical is stable. Buyers SHOULD preflight it with validate_input or in a sandbox before routing production budget and SHOULD filter it from default views unless the caller opts in. Experimental status never makes the deprecated named-format path preferable. This field is independent of the canonical's own experimental flag and replaces the earlier runtime_status enum."
        ),
    ] = False
    format_shape: Annotated[
        str | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. Recognized global pattern this custom shape is an instance of, drawn from the [format-shape vocabulary registry](/schemas/core/format-shape-vocabulary.json) (`branded_content`, `cross_screen_sponsorship`, `sponsorship_lockup`, `newsletter_sponsorship`, `ar_lens`, `playable`, `live_event_sponsorship`, …). Non-canonical values are valid (validators MAY soft-warn) — adopters CAN ship a shape that isn\'t yet in the registry. Adding entries is a vocabulary PR. Once a `format_shape` entry sees 2+ adopters with substantively similar `format_schema` content for 90+ days, the working group may promote it to a first-class canonical. Retired vocabulary entries `multi_state_display` and `multi_placement_takeover` remain temporarily recognizable for migration; new declarations MUST use their promoted canonicals and validators SHOULD emit `FORMAT_SHAPE_PROMOTED`. `roadblock` remains an inventory/exclusivity classifier and is not a promoted creative format.'
        ),
    ] = None
    v1_format_ref: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Authoritative v2 → v1 link, expressed as an array of one or more v1 `format_id` ({agent_url, id}) values. Each entry asserts that this canonical-formats declaration IS the same underlying format as the referenced v1 named format. Always an array (single-ref is `[{...}]`) so the multi-size case below has a clean wire shape — adopters surveyed in the SDK implementor review pushed for this over the lossy single-ref form.\n\nThe v2 declaration's `params` MUST narrow (be compatible with) each referenced v1 format's `requirements` — see the 'Narrows — formal definition' section in canonical-formats.mdx. SDKs comparing dual-emitted shapes (`Product.format_ids[]` ⊇ entries from `v1_format_ref` AND `Product.format_options[]` carrying this declaration) treat the link as the authoritative pairing and run the narrowing check between this declaration and EACH referenced v1 format file's `requirements`.\n\n**Multi-size fan-out (normative).** When the declaration carries `params.sizes: [{w,h}, ...]` (multi-size flexible slot), sellers SHOULD carry one `v1_format_ref[]` entry per size, each pointing at the per-size v1 named format in the AAO catalog. Example: a multi-size image declaration with `sizes: [300x250, 728x90, 970x250]` SHOULD carry `v1_format_ref: [{aao, display_300x250_image}, {aao, display_728x90_image}, {aao, display_970x250_image}]`. v1-only buyers then see the product on all three sizes via the `format_ids[]` dual-emission. When `v1_format_ref[]` count < `sizes[]` count, SDKs MUST emit `FORMAT_DECLARATION_V1_LOSSY_MULTI_SIZE` on the response `errors[]` (advisory, alongside the partial-coverage v1 emit — NOT in place of it). SDKs MAY (non-normative) fan out automatically by catalog lookup when `v1_format_ref[]` has length 1 and `sizes[]` has length N — opt-in, requires catalog access; sellers asserting refs is the source of truth.\n\nMutually exclusive with `canonical_formats_only: true` — a declaration can EITHER assert no v1 projection (`canonical_formats_only: true`) OR link to v1 named formats (`v1_format_ref[]`), never both. When neither is present, SDKs fall back to the resolution order in `v1-canonical-mapping.json` (seller's explicit `canonical` field on the v1 file → registry glob → structural match → fail-closed).\n\nThis is the v2-side authoritative replacement for the v1-side `canonical_parameters` field on `format.json` (which is deprecated for 3.1, removed at 4.0). Sellers SHOULD prefer authoring v2 declarations with `v1_format_ref[]` over mirroring the v2 shape onto v1 files via `canonical_parameters`; the directional link (v2 declaration → v1 identifiers) is the same fact without the parallel-shape drift surface.\n\n**AAO-hosted convention (normative).** For IAB-standard formats (image dimensions, VAST/DAAST tags, standard third-party tags, HTML5 banner bundles), sellers SHOULD point each `v1_format_ref[].agent_url` at the AAO-hosted canonical agent URL `https://creative.adcontextprotocol.org` and use the registry-published id (e.g., `display_300x250_image`, `video_vast_30s`, `audio_standard_30s`, `display_300x250_html`, `display_js`). This converges the v1-wire namespace: every seller's IAB MREC points at the same `{agent_url, id}` pair, so v1-only buyers' allowlists work uniformly. Without this convention, every publisher's 300x250 ships with a different `v1_format_ref` (theirs vs nytimes.example vs cnn.example vs …) and the v1 wire fragments into per-publisher namespaces — exactly what canonical-formats was designed to eliminate.\n\nFor platform-specific formats (Meta Reels, TikTok Spark, Snap Spotlight, etc.), each `v1_format_ref[].agent_url` SHOULD point at the platform's own agent_url when the platform has adopted AdCP and publishes its own `adagents.json` with `formats[]`. When the platform has NOT adopted AdCP, sellers SHOULD point at the AAO community-registry mirror — `https://creative.adcontextprotocol.org/translated/<platform>` + `id: <platform-format-name>` (e.g., `https://creative.adcontextprotocol.org/translated/meta` + `id: meta_reels`). This keeps the v1 namespace converged across all sellers selling that platform's inventory until the platform owns its own adagents.json.\n\n**Platform-adoption cutover (normative).** When a platform adopts AdCP and publishes its own adagents.json, sellers MUST update `v1_format_ref[].agent_url` to the platform's adopted agent_url in the same minor release as the AAO mirror entry's `superseded_by` field goes live (see `static/schemas/source/adagents.json#superseded_by`). The AAO mirror entry SHOULD continue serving for ≥1 minor release after `superseded_by` is set, returning an advisory 'superseded' marker so v1 buyer allowlists keyed on the mirror URL get an explicit signal rather than a silent break. **Identity-confusion note**: the mirror URL is *format-shape namespace*, NOT seller identity. Inventory authorization always flows from `authorized_agents[]` + publisher signing keys; a buyer matching `v1_format_ref[].agent_url` against an allowlist is matching format-shape provenance, not seller identity.\n\n**Mirror domain migration (3.1).** Earlier drafts used `https://mirror.adcontextprotocol.org/translated/<platform>`. As of this release, the convention is `https://creative.adcontextprotocol.org/translated/<platform>` — sibling content under the AAO catalog domain we already host. Adopters who hardcoded the earlier mirror URL MUST migrate to the new path; the canonical-formats.mdx migration section documents the move. No transitional redirect is currently published (the earlier subdomain was never provisioned).\n\nFor seller-bespoke formats (a publisher's `acme_homepage_takeover` that doesn't fit IAB conventions), each `v1_format_ref[].agent_url` is the seller's own agent_url and the id is seller-namespaced. These won't appear in `v1-canonical-mapping.json`'s registry; they're seller-asserted only.",
            min_length=1,
        ),
    ] = None
    format_schema: Annotated[
        platform_extension_ref.PlatformExtensionReference | None,
        Field(
            description='REQUIRED when `format_kind: "custom"`; otherwise MUST be absent. URI+digest reference to a fetchable schema describing this custom shape\'s actual `params` and `slots`. Same hosting model as `platform_extensions`: open-ecosystem publishers host the artifact at the canonical URI on their subdomain; closed-platform / walled-garden shapes resolve through the AAO mirror at `https://creative.adcontextprotocol.org/translated/...`. Buyer agents fetch by `uri@digest` (immutable per digest, aggressive caching, `Cache-Control: public, max-age=31536000, immutable`), validate `params` and `slots` against the fetched schema, and reason about manifests structurally — same mechanic as platform_extensions but at the format-structure level. Without `format_schema`, custom shapes would be opaque to buyer agents and the protocol would regress to per-seller integration code; that\'s why the schema is required, not optional.\n\n**Fetch contract (normative)** — `format_schema` is load-bearing for validation (unlike `platform_extensions`, which is informational on the *consumption* side). The *transport* rules below apply identically to BOTH fields — any SDK fetching a `platform-extension-ref.json` URI MUST apply this contract regardless of whether the field name is `format_schema` or `platform_extensions`. A shared SDK fetch path that drops to the weakest bar undermines `format_schema`\'s hardening. The consumption distinction (load-bearing vs informational) is about *what the body means*; the transport distinction is `https`-and-allowlisted regardless.\n\n- **Transport**: `https` only. Buyers MUST reject `http://`, `file://`, `data:`, and any non-`https` scheme. The URI MUST resolve to a JSON document that is itself a valid JSON Schema (Draft 07 or 2020-12; producers MUST declare `$schema`).\n- **SSRF protection**: buyers MUST resolve the URI hostname and reject if any resolved address is in RFC 1918 private space (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), loopback (`127.0.0.0/8`, `::1`), link-local (`169.254.0.0/16`, `fe80::/10`), CGNAT (`100.64.0.0/10`), or any RFC 6761 special-use name (`.local`, `.localhost`, `.internal`, `.test`, `.example`, `.invalid`). Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`, `kubernetes.default.svc`) are explicitly forbidden — these are credential-leak primitives. Buyers MUST pin the connection to the resolved IP (or re-resolve and re-validate the allowlist per request) to defeat DNS rebinding.\n- **HTTP redirects**: MUST be disabled. If a follow is implemented at all, the redirect target MUST pass the same scheme + SSRF + allowlist checks; otherwise the fetch hard-fails. Open redirects on same-origin paths are otherwise a free SSRF primitive.\n- **Response size cap**: response body MUST be capped at 1 MiB. Enforce during streaming, not after full buffering. Over-cap hard-fails identically to digest mismatch.\n- **Timeout**: SDKs SHOULD apply a fetch timeout ≤5 seconds. Timeout SHOULD be treated identically to an HTTP 5xx response (transient — retry policy at the SDK\'s discretion; on persistent failure surface as unresolved and skip the declaration for this session).\n- **Digest verification**: SHA-256 of the response body MUST equal `digest`. **Digest mismatch is a hard fail** — the buyer MUST treat the format declaration as unresolvable and MUST NOT validate manifests against the mismatched body. A divergent digest is either a malicious substitution or producer error; either way, falling back to the un-verified body breaks the trust model. Digest format: `sha256:` prefix + 64 lowercase hex characters. Cache key is `uri@digest`; digest mismatch MUST NOT be cached as a negative result keyed on `uri` alone (defeats CDN-flap recovery), and MUST be distinguishable in telemetry from network 5xx / 404 (sustained mismatch is a substitution-attack signal, not a flap).\n- **Sandboxing of `$ref`**: fetched schemas MAY use `$ref`. Buyers MUST resolve `$ref` only to URIs that are (a) same-origin as the parent `format_schema.uri` after RFC 3986 §6 normalization (lowercase scheme + host, strip default port, normalize path dot-segments, no userinfo component), OR (b) hosted under the AAO catalog domain (`https://creative.adcontextprotocol.org/...`), OR (c) intra-document JSON Pointer refs (`#/...`) bounded to the parent document\'s parsed tree. Cross-origin `$ref` to arbitrary URIs MUST be rejected. `$ref: file://...` MUST be rejected unconditionally. Transitive `$ref` chains MUST be bounded at depth ≤8 AND `$ref` count ≤256 across the resolved tree (depth 8 with breadth 100 per level is 10^16 nodes — depth alone is not enough). Publishers SHOULD inline rather than $ref where possible.\n- **Schema-compile bounds (DoS protection)**: validators MUST bound CPU/memory on fetched schemas. Recommended: compiled-schema keyword count ≤10 000, `pattern` regexes evaluated with a non-backtracking engine (re2) OR under a per-pattern timeout, per-manifest validation budget ≤250 ms (exceeded budget → treat manifest as invalid, surface telemetry signal). Without these, a \'valid\' schema with catastrophic regex backtracking or exponential `allOf`/`anyOf` expansion pins a CPU forever.\n- **Cache**: buyers cache fetched schemas by `uri@digest` and treat them as immutable (the same hosting contract as `platform_extensions`). On `404`, network partition, or persistent fetch failure, buyers SHOULD degrade gracefully (treat the declaration as unresolved, skip it for the current `get_products` response, surface via `errors[]` with the relevant code) rather than failing the entire session.\n- **Schema-not-valid handling**: if the fetched body parses as JSON but is not a valid JSON Schema, the buyer MUST treat the declaration as unresolvable (same as digest mismatch) and surface via `errors[]`. Validators MUST NOT attempt partial validation against an invalid schema.\n- **AAO catalog trust**: `https://creative.adcontextprotocol.org/*` is a single trust anchor in the same-origin allowlist; compromise of the catalog domain or its CA compromises every buyer agent. Catalog-served bodies MUST be digest-pinned identically to origin fetches (the digest is on the *parent* `format_schema.uri@digest`, not on the catalog response). Future hardening (signed bodies, transparency log) is tracked separately.'
        ),
    ] = None
    format_kind: Literal['audio_daast'] = 'audio_daast'
    params: audio_daast.CanonicalFormatDaastAudio

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 applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : Literal['audio_daast']
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var locale_policy : CreativeLocalePolicy | None
var macro_resolution_capabilities : list[MacroProcessingCapability] | None
var model_config
var params : CanonicalFormatDaastAudio
var publisher_domain : str | None
var sample_render_url : pydantic.networks.AnyUrl | None
var seller_preference : SellerPreference | None
var technical_requirements_complete : bool | None
var tracker_execution_contract : TrackerExecutionContract | None
var v1_format_ref : list[FormatReferenceStructuredObject] | None

Inherited members

class ProductIdentity (**data: Any)
Expand source code
class ProductIdentity(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    persistent_identifier: Annotated[
        StrictBool,
        Field(
            description='Whether delivery on this product has a persistent per-entity identifier suitable for identifier-backed reach, frequency, and frequency-cap enforcement. false does not prohibit modeled individuals or households measurement.'
        ),
    ]
    reach_methodology: Annotated[
        str | None,
        Field(
            description="Human-readable methodology for this product's custom reach unit. Required when the product reports reach or frequency with reach_unit custom, including frequency-only reporting.",
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var persistent_identifier : bool
var reach_methodology : str | None

Inherited members

class ProductMediaBuySupport (**data: Any)
Expand source code
class ProductMediaBuySupport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    frequency_cap: Annotated[
        Literal[True] | None,
        Field(
            description="This product can participate in the seller's shared counter for a root MediaBuy.frequency_cap. A buy mixing this product with one that lacks this declaration, or whose resolved supported_per_units omits the root cap's per value, is rejected atomically."
        ),
    ] = None
    frequency_cap_constraints: (
        media_buy_frequency_cap_support.MediaBuyFrequencyCapSupport | None
    ) = None
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var frequency_cap : Literal[True] | None
var frequency_cap_constraints : MediaBuyFrequencyCapSupport | None
var model_config

Inherited members

class ProductMediaBuySupportRequirements (**data: Any)
Expand source code
class ProductMediaBuySupportRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    frequency_cap: Annotated[
        Literal[True] | None,
        Field(
            description='Require product participation in one shared MediaBuy frequency-cap counter.'
        ),
    ] = None
    frequency_cap_constraints: (
        media_buy_frequency_cap_requirement.MediaBuyFrequencyCapRequirement | 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 frequency_cap : Literal[True] | None
var frequency_cap_constraints : MediaBuyFrequencyCapRequirement | None
var model_config

Inherited members

class ProductOfferFilters (**data: Any)
Expand source code
class ProductOfferFilters(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    delivery_type: delivery_type_1.DeliveryType | None = None
    exclusivity: exclusivity_1.Exclusivity | None = None
    is_fixed_price: Annotated[
        StrictBool | None,
        Field(
            description='Filter fixed-price versus auction offers. Contingent pricing matches neither value.'
        ),
    ] = None
    pricing_structures: Annotated[
        list[pricing_structure.PricingStructure] | None, Field(min_length=1)
    ] = None
    pricing_currencies: Annotated[list[PricingCurrency] | None, Field(min_length=1)] = None
    format_kinds: Annotated[list[str] | None, Field(min_length=1)] = None
    format_option_refs: Annotated[
        list[format_option_ref.FormatOptionReference] | None, Field(min_length=1)
    ] = None
    standard_formats_only: StrictBool | None = None
    min_exposures: Annotated[SchemaInt | None, Field(ge=1)] = None
    start_date: Annotated[
        date | None,
        Field(
            description='Fixed-flight availability filter: with end_date, declares the exact flight the buyer intends to run. Returned products MUST be able to serve that flight, and pricing and forecasts are scoped to it. Mutually exclusive with availability_horizon.'
        ),
    ] = None
    end_date: Annotated[
        date | None,
        Field(
            description='Fixed-flight availability filter end. See start_date. Mutually exclusive with availability_horizon.'
        ),
    ] = None
    availability_horizon: Annotated[
        AvailabilityHorizon | None,
        Field(
            description="Flexible-window availability discovery: the buyer is open to any bookable window inside [start_time, end_time) and asks the seller to describe when the returned inventory can run, instead of filtering to one exact flight. Sellers that support this field partition the horizon into time-dimensioned forecast rows (forecast-dimension-time) carrying availability_status; sellers that cannot cover the full horizon signal the gap via the response's incomplete[] mechanism. Unlike start_date/end_date this is not an eligibility filter — products remain returnable when only part of the horizon is open. The resulting availability is a snapshot bounded by the forecast's valid_until, never a hold. Mutually exclusive with start_date and end_date, which declare a fixed flight; buyers that already know their dates use those instead."
        ),
    ] = None
    budget_range: budget_range_1.BudgetRange | None = None
    countries: Annotated[
        list[Country] | None,
        Field(
            description="Filter by country coverage using ISO 3166-1 alpha-2 codes (e.g., ['US', 'CA', 'GB']). Returns products whose geographic coverage includes at least one of the specified countries. This is a product attribute filter, not a delivery-targeting instruction.",
            min_length=1,
        ),
    ] = None
    regions: Annotated[
        list[Region] | None,
        Field(
            description='Inventory coverage in the specified ISO 3166-2 subdivisions: OR within this field, AND across offer filters. Does not add delivery targeting, require targeting support, or rescope pricing or forecasts.',
            min_length=1,
        ),
    ] = None
    metros: Annotated[
        list[Metro] | None,
        Field(
            description='Inventory coverage in the specified metro areas (system and code): OR within this field, AND across offer filters. Does not add delivery targeting, require targeting support, or rescope pricing or forecasts.',
            min_length=1,
        ),
    ] = None
    postal_areas: Annotated[
        list[postal_area.PostalArea] | None,
        Field(
            description='Inventory coverage in the specified postal areas: OR within this field, AND across offer filters. Does not add delivery targeting, require targeting support, or rescope pricing or forecasts.',
            min_length=1,
        ),
    ] = None
    geo_proximity: Annotated[
        list[GeoProximityItem] | None,
        Field(
            description='Inventory coverage in the specified proximity boundaries: OR within this field, AND across offer filters. Does not add delivery targeting, require targeting support, or rescope pricing or forecasts.',
            min_length=1,
        ),
    ] = None
    property_list: Annotated[
        property_list_ref.PropertyListReference | None,
        Field(
            description='Reference to an externally managed property list. When provided, the seller filters products to only those available on properties in the list. This narrows which publisher inventory is returned; it is a product attribute filter, not a delivery-targeting instruction.'
        ),
    ] = None
    channels: Annotated[list[channels_1.MediaChannel] | None, Field(min_length=1)] = None
    video_placement_types: Annotated[
        list[video_placement_type.VideoPlacementType] | None, Field(min_length=1)
    ] = None
    audio_distribution_types: Annotated[
        list[audio_distribution_type.AudioDistributionType] | None, Field(min_length=1)
    ] = None
    sponsored_placement_types: Annotated[
        list[sponsored_placement_type.SponsoredPlacementType] | None, Field(min_length=1)
    ] = None
    social_placement_surfaces: Annotated[
        list[social_placement_surface.SocialPlacementSurface] | None, Field(min_length=1)
    ] = None
    trusted_match: TrustedMatch | None = None
    required_features: Annotated[
        canonical_media_buy_features.CanonicalMediaBuyFeatures | None,
        Field(description='Canonical protocol features the seller must support.'),
    ] = None
    required_performance_standards: Annotated[
        list[RequiredPerformanceStandard] | None, Field(min_length=1)
    ] = None
    required_metrics: Annotated[
        list[available_metric.AvailableMetric] | None, Field(min_length=1)
    ] = None
    required_vendor_metrics: Annotated[list[RequiredVendorMetric] | None, Field(min_length=1)] = (
        None
    )
    audience_evidence_requirements: (
        product_audience_evidence_requirements.ProductAudienceEvidenceRequirements | None
    ) = None
    ext: ext_1.ExtensionObject | 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 audience_evidence_requirements : ProductAudienceEvidenceRequirements | None
var audio_distribution_types : list[AudioDistributionType] | None
var availability_horizon : AvailabilityHorizon | None
var budget_range : BudgetRange | None
var channels : list[MediaChannel] | None
var countries : list[Country] | None
var delivery_type : DeliveryType | None
var end_date : datetime.date | None
var exclusivity : Exclusivity | None
var ext : ExtensionObject | None
var format_kinds : list[str] | None
var format_option_refs : list[FormatOptionReference1 | FormatOptionReference2] | None
var geo_proximity : list[GeoProximityItem] | None
var is_fixed_price : bool | None
var metros : list[Metro] | None
var min_exposures : int | None
var model_config
var postal_areas : list[PostalArea] | None
var pricing_currencies : list[PricingCurrency] | None
var pricing_structures : list[PricingStructure] | None
var property_list : PropertyListReference | None
var regions : list[Region] | None
var required_features : CanonicalMediaBuyFeatures | None
var required_metrics : list[AvailableMetric] | None
var required_performance_standards : list[RequiredPerformanceStandard] | None
var required_vendor_metrics : list[RequiredVendorMetric] | None
var social_placement_surfaces : list[SocialPlacementSurface] | None
var sponsored_placement_types : list[SponsoredPlacementType] | None
var standard_formats_only : bool | None
var start_date : datetime.date | None
var trusted_match : TrustedMatch | None
var video_placement_types : list[VideoPlacementType] | None

Inherited members

class ProductSignalTargetingOption (**data: Any)
Expand source code
class ProductSignalTargetingOption(SignalListing):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_agent_segment_id: Annotated[
        str | None,
        Field(
            description='Optional opaque resolved-segment or seller execution handle for this signal. Omit when signal_ref plus the value expression is sufficient for the seller to resolve the signal. Include when the seller exposes a distinct runtime or activation handle that buyers must echo in packages[].targeting_overlay.signal_targeting_groups.groups[].signals[].signal_agent_segment_id. Buyers SHOULD echo this handle verbatim rather than reconstructing identity from categorical values; providers MAY namespace handles so cross-provider identity stays legible without a shared taxonomy registry.'
        ),
    ] = None
    activation_status: Annotated[
        ActivationStatus | None,
        Field(
            description="Whether this signal option is ready to select on create_media_buy for the requesting account. 'ready' means the buyer can select it directly. 'requires_activation' means the buyer must activate the signal first or include an activation_key the seller accepts."
        ),
    ] = ActivationStatus.ready
    allowed_targeting_modes: Annotated[
        list[AllowedTargetingMode] | None,
        Field(
            description="How this signal may be used when composing package-level signal targeting groups. 'include' means the signal may appear in an 'any' child group. 'exclude' means the signal may appear in a 'none' child group. Omit when the signal is include-only. This field declares the allowed buy-time group operator; binary package signal entries still use value=true in both include and exclude groups.",
            min_length=1,
        ),
    ] = [AllowedTargetingMode.include]
    default_selected: Annotated[
        StrictBool | None,
        Field(
            description="Whether the seller recommends or preselects this signal when composing this product. Buyers may remove it unless signal_targeting_rules.selection_mode is 'fixed'. When selection_mode is 'fixed', sellers apply default_selected signals even if the buyer omits signal_targeting_groups and MUST echo the applied entries on the resulting package state."
        ),
    ] = False
    selection_group: Annotated[
        str | None,
        Field(
            description='Optional product-defined composability bucket for signal options, such as alternative audience tiers, a key-value targeting plane, or an audience-segment targeting plane. Signals in the same selection_group are expected to be OR-combinable inside one child group for a given targeting mode, subject to signal_targeting_rules. Use different selection_group values when the product requires separate ANDed clauses, such as signal sets backed by different platform targeting primitives that cannot be collapsed into one child group. selection_group is a product-option grouping key, not a reference to one child object in packages[].targeting_overlay.signal_targeting_groups.groups[]. Sellers can use signal_targeting_rules.max_selected_per_group and signal_targeting_rules.selection_group_rules with selection_group to guide and validate storefront composition.'
        ),
    ] = None
    pricing_options: Annotated[
        list[vendor_pricing_option.VendorPricingOption] | None,
        Field(
            description='Signal pricing options available when this signal is selected on this product. Product-scoped pricing is authoritative for this product; if get_signals exposes a different default rate card, use this product-scoped price when composing the buy. Buyers pass the selected pricing_option_id in packages[].targeting_overlay.signal_targeting_groups.groups[].signals[].pricing_option_id. Omit when the signal is bundled into the product price or has no incremental cost.',
            min_length=1,
        ),
    ] = None
    signal_ref: Annotated[
        signal_ref.SignalRef,
        Field(
            description="Canonical signal reference. Use scope 'product' for a product-local signal defined by this listing; use scope 'data_provider' with data_provider_domain for a signal defined in a data provider's published adagents.json signals[]; use scope 'signal_source' with signal_source_url for a source-native signal."
        ),
    ]

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 activation_status : ActivationStatus | None
var allowed_targeting_modes : list[AllowedTargetingMode] | None
var default_selected : bool | None
var model_config
var pricing_options : list[VendorPricingOption7 | VendorPricingOption8 | VendorPricingOption9 | VendorPricingOption10 | VendorPricingOption11] | None
var selection_group : str | None
var signal_agent_segment_id : str | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3

Inherited members

class ProductTargetingResolution (**data: Any)
Expand source code
class ProductTargetingResolution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    modifications: Annotated[
        list[targeting_modification.TargetingModification],
        Field(
            description='Ordered changes applied to the requested targeting_overlay. Sellers apply entries in array order and MUST validate the complete resulting overlay before returning the product.',
            min_length=1,
        ),
    ]
    effective_targeting_digest: Annotated[
        str | None,
        Field(
            description='Optional digest of the canonical effective targeting overlay. Until AdCP defines a cross-implementation canonicalization algorithm, this value is an opaque seller audit handle and buyers MUST NOT attempt to reproduce or compare it across sellers.',
            pattern='^sha256:[0-9a-f]{64}$',
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 effective_targeting_digest : str | None
var ext : ExtensionObject | None
var model_config
var modifications : list[TargetingModification1 | TargetingModification2]

Inherited members

class ProductionStatus (*args, **kwds)
Expand source code
class ProductionStatus(StrEnum):
    not_due = 'not_due'
    pending = 'pending'
    published = 'published'
    failed = 'failed'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var failed
var not_due
var pending
var published
class Progress (**data: Any)
Expand source code
class Progress(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0)
    ] = None
    current_step: Annotated[
        str | None, Field(description='Current step or phase of the operation')
    ] = None
    total_steps: Annotated[
        SchemaInt | None, Field(description='Total number of steps in the operation', ge=1)
    ] = None
    step_number: Annotated[SchemaInt | None, Field(description='Current step number', 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

Class variables

var current_step : str | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class Property (**data: Any)
Expand source code
class Property(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    property_id: Annotated[
        property_id_1.PropertyId | None,
        Field(
            description='Unique identifier for this property (optional). Enables referencing properties by ID instead of repeating full objects.'
        ),
    ] = None
    property_type: Annotated[
        property_type_1.PropertyType, Field(description='Type of advertising property')
    ]
    name: Annotated[str, Field(description='Human-readable property name')]
    identifiers: Annotated[
        list[Identifier], Field(description='Array of identifiers for this property', min_length=1)
    ]
    tags: Annotated[
        list[property_tag.PropertyTag] | None,
        Field(
            description='Tags for categorization and grouping (e.g., network membership, content categories)'
        ),
    ] = None
    supported_channels: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description="Advertising channels this property supports (e.g., ['display', 'olv', 'social']). Publishers declare which channels their inventory aligns with. Properties may support multiple channels. See the Media Channel Taxonomy for definitions."
        ),
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            description='Domain where adagents.json should be checked for authorization validation. Optional in adagents.json (file location implies domain).'
        ),
    ] = 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 identifiers : list[Identifier]
var model_config
var name : str
var property_id : PropertyId | None
var property_type : PropertyType
var publisher_domain : str | None
var supported_channels : list[MediaChannel] | None
var tags : list[PropertyTag] | None

Inherited members

class PropertyDeliveryMetrics (**data: Any)
Expand source code
class PropertyDeliveryMetrics(DeliveryMetrics):
    publisher_domain: Annotated[
        str,
        Field(
            description='Publisher or platform authority that namespaces the operational identifier, including when the surface is not registered in adagents.json.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    identifier: Annotated[
        identifier_1.Identifier,
        Field(
            description='Primary operational identifier of the property that delivered. Required even when catalog enrichment is unavailable.'
        ),
    ]
    property_ref: Annotated[
        property_ref_1.PropertyReference | None,
        Field(
            description="Canonical publisher-scoped catalog identity when the delivered property resolves to adagents.json. Its publisher_domain MUST equal the row's publisher_domain."
        ),
    ] = None
    property_name: Annotated[
        str | None,
        Field(
            description='Current human-readable property name. Convenience metadata only; property_ref is stable identity.'
        ),
    ] = None
    impressions: Any
    spend: Any

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 identifier : Identifier
var impressions : Any
var model_config
var property_name : str | None
var property_ref : PropertyReference | None
var publisher_domain : str
var spend : Any

Inherited members

class PropertyId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class PropertyId(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-z0-9_]+$'}
    _json_schema_extra = {
        'description': 'Identifier for a publisher property. Must be lowercase alphanumeric with underscores only.',
        'examples': ['cnn_ctv_app', 'homepage', 'mobile_ios', 'instagram'],
        'title': 'Property ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class PropertyListReference (**data: Any)
Expand source code
class PropertyListReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[AnyUrl, Field(description='URL of the agent managing the property list')]
    list_id: Annotated[
        str, Field(description='Identifier for the property list within the agent', min_length=1)
    ]
    auth_token: Annotated[
        str | None,
        Field(
            description='JWT or other authorization token for accessing the list. Optional if the list is public or caller has implicit access.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var auth_token : str | None
var list_id : str
var model_config

Inherited members

class PropertyPayload (**data: Any)
Expand source code
class PropertyPayload(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    property_rid: UUID | None = None
    classification: Classification | None = None
    source: PropertySource | None = None
    identifiers: Annotated[list[identifier.Identifier] | None, Field(min_length=1)] = None
    publisher_domain: Domain | None = None
    property: Annotated[
        property_1.Property | None,
        Field(description='Optional full post-change property object when available.'),
    ] = None
    changed_fields: ChangedFields | 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

Subclasses

Class variables

var changed_fields : ChangedFields | None
var classification : Classification | None
var identifiers : list[Identifier] | None
var model_config
var property : Property | None
var property_rid : uuid.UUID | None
var publisher_domain : Domain | None
var source : PropertySource | None

Inherited members

class PropertyReference (**data: Any)
Expand source code
class PropertyReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description='Domain where the adagents.json declaring this property is hosted.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    property_id: Annotated[
        property_id_1.PropertyId,
        Field(description="Property ID from the publisher's adagents.json property catalog."),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var property_id : PropertyId
var publisher_domain : str

Inherited members

class PropertySource (*args, **kwds)
Expand source code
class PropertySource(StrEnum):
    authoritative = 'authoritative'
    enriched = 'enriched'
    contributed = 'contributed'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var authoritative
var contributed
var enriched
class PropertyTag (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class PropertyTag(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-z0-9_]+$'}
    _json_schema_extra = {
        'description': 'Tag for categorizing publisher properties. Must be lowercase alphanumeric with underscores only.',
        'examples': ['ctv', 'premium', 'news', 'sports', 'meta_network', 'social_media'],
        'title': 'Property Tag',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class PropertyType (*args, **kwds)
Expand source code
class PropertyType(StrEnum):
    house = 'house'
    apartment = 'apartment'
    condo = 'condo'
    townhouse = 'townhouse'
    land = 'land'
    commercial = 'commercial'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var apartment
var commercial
var condo
var house
var land
var townhouse
class Proposal (**data: Any)
Expand source code
class Proposal(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    proposal_id: Annotated[
        str,
        Field(
            description='Unique identifier for this proposal. Used to finalize a draft proposal and to execute a committed proposal via create_media_buy.',
            max_length=255,
        ),
    ]
    name: Annotated[
        str, Field(description='Human-readable name for this media plan proposal', max_length=500)
    ]
    description: Annotated[
        str | None,
        Field(
            description='Explanation of the proposal strategy and what it achieves', max_length=2000
        ),
    ] = None
    allocations: Annotated[
        list[product_allocation.ProductAllocation],
        Field(
            description='Products and budget constraints in this plan. Fixed proposals require allocation_percentage on every entry and percentages MUST sum to 100. Seller-optimized proposals forbid exact allocation_percentage and may instead supply min_spend_target_percentage and max_spend_percentage, each only when the seller advertises the matching package-control capability (seller_optimized_min_spend_targets, seller_optimized_package_budgets). Publishers are responsible for validating cross-entry sums; buyers SHOULD validate them before execution.',
            min_length=1,
        ),
    ]
    budget_allocation: Annotated[
        budget_allocation_1.BudgetAllocation | None,
        Field(
            description='How the executed total budget is allocated across proposal products. Omit for legacy fixed proposals.'
        ),
    ] = None
    pacing: Annotated[
        pacing_1.Pacing | None,
        Field(
            description='Recommended aggregate pacing for the executed media-buy budget. On a committed proposal this is part of the firm delivery terms.'
        ),
    ] = None
    frequency_cap: Annotated[
        media_buy_frequency_cap.MediaBuyFrequencyCap | None,
        Field(
            description='Aggregate cap bound into this legacy proposal. It is authoritative when the proposal is executed and uses one counter across its packages.'
        ),
    ] = None
    proposal_status: Annotated[
        proposal_status_1.ProposalStatus | None,
        Field(
            description="Lifecycle status of this proposal and the per-proposal source of truth for whether finalization is required before create_media_buy. When absent, the proposal is ready to buy (backward compatible). 'draft' means indicative pricing — finalize via refine before purchasing. 'committed' means firm pricing with inventory reserved until expires_at and executable via create_media_buy."
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description='When this proposal expires and can no longer be executed. For draft proposals, indicates when indicative pricing becomes stale. For committed proposals, indicates when the inventory hold lapses — the buyer must call create_media_buy before this time.'
        ),
    ] = None
    insertion_order: Annotated[
        insertion_order_1.InsertionOrder | None,
        Field(
            description='Formal insertion order attached to a committed proposal. Present when the seller requires a signed agreement before the media buy can proceed. The buyer references the io_id in io_acceptance on create_media_buy.'
        ),
    ] = None
    total_budget_guidance: Annotated[
        TotalBudgetGuidance | None, Field(description='Optional budget guidance for this proposal')
    ] = None
    brief_alignment: Annotated[
        str | None,
        Field(
            description='Explanation of how this proposal aligns with the campaign brief',
            max_length=2000,
        ),
    ] = None
    forecast: Annotated[
        delivery_forecast.DeliveryForecast | None,
        Field(
            description='Aggregate forecasted delivery metrics for the entire proposal. When both proposal-level and allocation-level forecasts are present, the proposal-level forecast is authoritative for total delivery estimation.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 allocations : list[ProductAllocation]
var brief_alignment : str | None
var budget_allocation : BudgetAllocation1 | BudgetAllocation2 | None
var description : str | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var forecast : DeliveryForecast | None
var frequency_cap : MediaBuyFrequencyCap | None
var insertion_order : InsertionOrder | None
var model_config
var name : str
var pacing : Pacing | None
var proposal_id : str
var proposal_status : ProposalStatus | None
var total_budget_guidance : TotalBudgetGuidance | None

Inherited members

class ProposalKind (*args, **kwds)
Expand source code
class ProposalKind(StrEnum):
    new_media_buy = 'new_media_buy'
    media_buy_update = 'media_buy_update'
    media_buy_cancellation = 'media_buy_cancellation'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var media_buy_cancellation
var media_buy_update
var new_media_buy
class Protocol (*args, **kwds)
Expand source code
class Protocol(StrEnum):
    https = 'https'
    http = 'http'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var http
var https
class ProtocolEnvelope (**data: Any)
Expand source code
class ProtocolEnvelope(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    context_id: Annotated[
        str | None,
        Field(
            description='Transport-managed conversation identifier. On A2A, this maps to the native Message/Task `contextId` used to associate messages with a conversation; it is not carried inside the AdCP DataPart. On MCP, a request-body `context_id`, where admitted by the selected request schema, is a compatibility-only field: servers MUST ignore it, callers MUST NOT rely on it for continuity, and it MUST NOT select session state, identity, account, authorization, task continuation, or idempotency scope. MCP continuity, if provided, comes from the transport session. Distinct from `context` (per-request opaque echo, see below) and from `task_id` (AdCP operation tracking).'
        ),
    ] = None
    context: Annotated[
        context_1.ContextObject | None,
        Field(
            description='Per-request opaque caller-supplied correlation object echoed unchanged in the response. Used for buyer-side tracking (UI session IDs, trace IDs, custom metadata) that the agent MUST preserve byte-for-byte without parsing. Distinct from `context_id` (transport-managed A2A conversation correlation or MCP compatibility metadata) — `context` is caller-owned echo and never selects transport state. Both MAY appear on the same response.\n\n**Relationship to per-task body-level `context` declarations.** Many task request/response schemas (147 as of 3.1) already declare a body-level `context` field that `$ref`s `/schemas/core/context.json` at the body root. Under the flat-on-the-wire MCP serialization (see `notes` below), envelope-level `context` and body-level `context` occupy the same key on the response root — they are NOT separate fields, they MUST share the same value, and they MUST both `$ref` `core/context.json`. The envelope declaration is **authoritative** for the schema definition; per-task body declarations are mirrors retained for tooling reasons (SDK codegen completeness, per-task validation against the response schema in isolation). Future versions MAY drop body-level `context` declarations from per-task schemas; conformance does not require either declaration to be present, only that the wire value `$ref`s `core/context.json`.'
        ),
    ] = None
    task_id: Annotated[
        str | None,
        Field(
            description='Unique identifier for tracking asynchronous operations. Present when a task requires extended processing time. Used to query task status and retrieve results when complete.'
        ),
    ] = None
    status: Annotated[
        task_status.TaskStatus,
        Field(
            description='Current AdCP task state or structured outcome. Indicates whether the task completed, is in progress, was submitted for async processing, failed, requires user input, or returned a typed business rejection. REQUIRED on every task response envelope. Synchronous tasks (including read-only metadata calls like `get_adcp_capabilities`) normally emit `status: "completed"`; a task-specific rejection arm emits `status: "rejected"` without turning the transport into a failure. Async tasks emit `submitted`, `working`, `input-required`, etc. per their lifecycle. Agents MUST NOT emit the legacy task_status or response_status fields alongside this field — the status field is the single authoritative AdCP response state.'
        ),
    ] = task_status.TaskStatus.completed
    message: Annotated[
        str | None,
        Field(
            description='Human-readable summary of the task result. Provides natural language explanation of what happened, suitable for display to end users or for AI agent comprehension. Generated by the protocol layer based on the task response.'
        ),
    ] = None
    timestamp: Annotated[
        AwareDatetime | None,
        Field(
            description='ISO 8601 timestamp when the response was generated. Useful for debugging, logging, cache validation, and tracking async operation progress.'
        ),
    ] = None
    replayed: Annotated[
        StrictBool | None,
        Field(
            description="Set to true when this response was returned from the idempotency cache rather than from a fresh execution. Set to false (or omitted) when the request was executed fresh. Buyers use this to distinguish cached replays from new executions — matters for billing reconciliation, audit logs, state-machine routing (cached state-tracking fields are historical snapshots, not current state — re-read via the resource's read endpoint), and any downstream system that assumes exactly-once event semantics. `replayed` appears only when the request actually resolved through the idempotency cache. Pure reads may ignore an optional `idempotency_key`; when a seller voluntarily caches keyed reads, those responses use the same replay indicator and full cache contract."
        ),
    ] = False
    adcp_error: Annotated[
        error.Error | None,
        Field(
            description="Transport-envelope error signal for fatal task failures. Per the two-layer model in `error-handling.mdx#envelope-vs-payload-errors-the-two-layer-model`, a fatal task failure SHOULD populate both this envelope-level field AND the payload's `errors[]` array — the envelope carries a typed, extractable error so MCP/A2A clients can dispatch without re-parsing the payload, while the payload's structured `errors[]` remains the canonical normative shape. Non-fatal warnings populate ONLY `payload.errors[]` with `severity: warning` — the envelope MUST NOT carry `adcp_error` for non-failures."
        ),
    ] = None
    push_notification_config: Annotated[
        push_notification_config_1.PushNotificationConfig | None,
        Field(
            description='AdCP application-layer webhook configuration for async task updates over MCP, A2A, or REST. Echoed from the request to confirm webhook settings. It is distinct from transport-native progress or A2A TaskPushNotificationConfig delivery and can outlive the originating transport session.'
        ),
    ] = None
    governance_context: Annotated[
        str | None,
        Field(
            description='Opaque authorization context issued only by an approved check_governance decision. Buyers attach it to governed requests across protocol roles (media buys, rights acquisitions, signal activations, creative services); receiving services persist it and forward it on subsequent execution and lifecycle checks. The context is the authoritative plan binding at service boundaries, so a service MUST NOT require a separate plan_id.\n\nGovernance agents MUST emit a compact JWS per the AdCP JWS profile. Verifiers validate standard authorization claims such as signature, issuer, audience, expiry, and replay protection, but intermediaries MUST NOT interpret embedded governance state for business logic. A conditions or denied verdict never carries an authorization context.\n\nThis is the primary correlation key for audit and reporting across the governance lifecycle.',
            max_length=4096,
            min_length=1,
            pattern='^[\\x20-\\x7E]+$',
        ),
    ] = None
    payload: Annotated[
        dict[str, Any] | None,
        Field(
            description='Conceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json). `payload` is a documentary construct — it is NOT a required wire field, and its on-the-wire shape depends on transport (see Transport serialization below). Task response schemas declare body fields without wrapping them in a `payload` object; the wire representation places those body fields per transport convention. On MCP the body fields appear as siblings of envelope fields at the root of the tool response; on A2A they appear inside `task.artifacts[0].parts[].DataPart`; on REST they appear at the root of the JSON body.'
        ),
    ] = 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 adcp_error : Error | None
var context : ContextObject | None
var context_id : str | None
var governance_context : str | None
var message : str | None
var model_config
var payload : dict[str, typing.Any] | None
var push_notification_config : PushNotificationConfig | None
var replayed : bool | None
var status : TaskStatus
var task_id : str | None
var timestamp : pydantic.types.AwareDatetime | None

Inherited members

class ProtocolResponse (**data: Any)
Expand source code
class ProtocolResponse(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    message: Annotated[str, Field(description='Human-readable summary')]
    context_id: Annotated[
        str | None,
        Field(
            description='Transport-managed conversation identifier. Maps to native contextId on A2A; compatibility metadata only on MCP and not a continuation or authorization mechanism.'
        ),
    ] = None
    data: Annotated[
        Any | None,
        Field(
            description='AdCP task-specific response data (see individual task response schemas)'
        ),
    ] = 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 context_id : str | None
var data : typing.Any | None
var message : str
var model_config

Inherited members

class ProvenanceRequirements (**data: Any)
Expand source code
class ProvenanceRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    require_digital_source_type: Annotated[
        StrictBool | None,
        Field(
            description='When true, the seller requires creatives to include a `digital_source_type` field in their provenance, set to a valid value from the `digital-source-type` enum (not null or absent). Submissions that omit this field are rejected with `PROVENANCE_DIGITAL_SOURCE_TYPE_MISSING`. Supports EU AI Act Art. 50 and CA SB 942 compliance workflows where AI disclosure metadata must be present at the protocol level.'
        ),
    ] = None
    require_synthetic_depiction: Annotated[
        StrictBool | None,
        Field(
            description='When true, the seller requires creatives to include an assessed `synthetic_depiction` boolean in their resolved provenance. Both true and false satisfy the requirement; absence means unassessed and is rejected with `PROVENANCE_SYNTHETIC_DEPICTION_MISSING`. This gate requires a declaration only — it does not establish consent, legality, or independent verification.'
        ),
    ] = None
    require_disclosure_metadata: Annotated[
        StrictBool | None,
        Field(
            description='When true, the seller requires creatives to include a `disclosure` object in their provenance with `disclosure.required` set to a boolean value (true or false). When `disclosure.required` is true, at least one entry in `disclosure.jurisdictions` is expected. Submissions that omit `disclosure.required` are rejected with `PROVENANCE_DISCLOSURE_MISSING`.'
        ),
    ] = None
    require_embedded_provenance: Annotated[
        StrictBool | None,
        Field(
            description='When true, the seller requires creatives to include at least one `embedded_provenance` entry. For pipelines where sidecar metadata is stripped by intermediaries, this ensures provenance data persists through delivery. Submissions that omit `embedded_provenance` are rejected with `PROVENANCE_EMBEDDED_MISSING`.'
        ),
    ] = 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 model_config
var require_digital_source_type : bool | None
var require_disclosure_metadata : bool | None
var require_embedded_provenance : bool | None
var require_synthetic_depiction : bool | None

Inherited members

class PublishedPostAsset1 (**data: Any)
Expand source code
class PublishedPostAsset1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['published_post'],
        Field(
            description='Discriminator identifying this as a published-post reference asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'published_post'
    post_url: Annotated[
        AnyUrl,
        Field(
            description='Canonical URL for the published post. Preferred when the platform exposes a stable public or authenticated URL.'
        ),
    ]
    platform: Annotated[
        str | None,
        Field(
            description="Optional platform or publisher namespace for the referenced post. Informational unless the seller's product declaration or platform extension narrows the accepted values."
        ),
    ] = None
    platform_post_id: Annotated[
        str | None,
        Field(
            description='Optional platform-native post identifier when a URL alone is not stable or not available. Buyers SHOULD include `platform` when using `platform_post_id` without `post_url`, unless the product or format declaration already narrows the platform. Platform-specific identifier semantics belong in platform_extensions; this field is only an opaque reference.'
        ),
    ] = None
    identity_ref: Annotated[
        IdentityRef | None,
        Field(
            description='Optional identity hint for the authoring handle/page/channel that owns the post. Sellers MUST verify authorization from platform state; buyers MUST NOT use this object as proof of authorization.'
        ),
    ] = None
    published_at: Annotated[
        AwareDatetime | None,
        Field(description='When the referenced post was originally published, if known.'),
    ] = None
    reference_authorization: Annotated[
        ReferenceAuthorization | None,
        Field(
            description='Server-emitted, seller-observed authorization state for the referenced post or identity. Sellers MAY return this object on read surfaces. On write requests, sellers MUST ignore buyer-supplied `reference_authorization.status` and other authorization-state claims unless a platform extension explicitly defines a signed proof shape and the seller verifies that proof.'
        ),
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this reference asset, overrides manifest-level provenance.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['published_post']
var identity_ref : IdentityRef | None
var model_config
var platform : str | None
var platform_post_id : str | None
var post_url : pydantic.networks.AnyUrl
var provenance : Provenance | None
var published_at : pydantic.types.AwareDatetime | None
var reference_authorization : ReferenceAuthorization | None

Inherited members

class PublishedPostAsset2 (**data: Any)
Expand source code
class PublishedPostAsset2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['published_post'],
        Field(
            description='Discriminator identifying this as a published-post reference asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'published_post'
    post_url: Annotated[
        AnyUrl | None,
        Field(
            description='Canonical URL for the published post. Preferred when the platform exposes a stable public or authenticated URL.'
        ),
    ] = None
    platform: Annotated[
        str | None,
        Field(
            description="Optional platform or publisher namespace for the referenced post. Informational unless the seller's product declaration or platform extension narrows the accepted values."
        ),
    ] = None
    platform_post_id: Annotated[
        str,
        Field(
            description='Optional platform-native post identifier when a URL alone is not stable or not available. Buyers SHOULD include `platform` when using `platform_post_id` without `post_url`, unless the product or format declaration already narrows the platform. Platform-specific identifier semantics belong in platform_extensions; this field is only an opaque reference.'
        ),
    ]
    identity_ref: Annotated[
        IdentityRef | None,
        Field(
            description='Optional identity hint for the authoring handle/page/channel that owns the post. Sellers MUST verify authorization from platform state; buyers MUST NOT use this object as proof of authorization.'
        ),
    ] = None
    published_at: Annotated[
        AwareDatetime | None,
        Field(description='When the referenced post was originally published, if known.'),
    ] = None
    reference_authorization: Annotated[
        ReferenceAuthorization1 | None,
        Field(
            description='Server-emitted, seller-observed authorization state for the referenced post or identity. Sellers MAY return this object on read surfaces. On write requests, sellers MUST ignore buyer-supplied `reference_authorization.status` and other authorization-state claims unless a platform extension explicitly defines a signed proof shape and the seller verifies that proof.'
        ),
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this reference asset, overrides manifest-level provenance.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['published_post']
var identity_ref : IdentityRef | None
var model_config
var platform : str | None
var platform_post_id : str
var post_url : pydantic.networks.AnyUrl | None
var provenance : Provenance | None
var published_at : pydantic.types.AwareDatetime | None
var reference_authorization : ReferenceAuthorization1 | None

Inherited members

class PublisherAdagentsPayload (**data: Any)
Expand source code
class PublisherAdagentsPayload(Payload10):
    pass

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 model_config

Inherited members

class PublisherDesignatedPreviewProvider (**data: Any)
Expand source code
class PublisherDesignatedPreviewProvider(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='HTTPS URL of the delegated creative-agent endpoint. Buyers call get_adcp_capabilities and preview_creative on this endpoint. They MUST allow only public IPs, pin DNS resolution through connection, refuse redirects, cap time and response size, and attach provider credentials only after exact normalized-origin binding.'
        ),
    ]
    authority: Annotated[
        Literal['publisher_designated'],
        Field(
            description="Explicitly states that authority comes from the publisher-hosted placement declaration. The provider's rendering_origin metadata is informational and remains non-authoritative elsewhere."
        ),
    ] = 'publisher_designated'
    routes: Annotated[list[Route], Field(min_length=1)]

    @field_validator('agent_url')
    @classmethod
    def _require_https_agent_url(cls, value: AnyUrl) -> AnyUrl:
        if value.scheme != 'https':
            raise ValueError('agent_url must use https')
        return value

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var authority : Literal['publisher_designated']
var model_config
var routes : list[Route]

Inherited members

class PublisherDoohPlacementAttributes (**data: Any)
Expand source code
class PublisherDoohPlacementAttributes(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    slot_duration_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Default scheduled duration of one ad slot in seconds. This is an inventory fact used for loop and share calculations, not the creative-duration contract.',
            ge=1,
        ),
    ] = None
    loop_duration_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Duration of the full ad loop rotation in seconds and the canonical source for loop duration.',
            ge=1,
        ),
    ] = None
    screen_resolution: PublisherDoohScreenResolution | None = None
    motion: Annotated[
        dooh_motion_type.DoohMotionType | None,
        Field(
            description='Physical motion capability of a visual DOOH screen, not an accepted-format declaration. Omit for audio-only placements.'
        ),
    ] = 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 loop_duration_seconds : int | None
var model_config
var motion : DoohMotionType | None
var screen_resolution : PublisherDoohScreenResolution | None
var slot_duration_seconds : int | None

Inherited members

class PublisherDoohScreenResolution (**data: Any)
Expand source code
class PublisherDoohScreenResolution(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    width: Annotated[SchemaInt, Field(description='Screen width in pixels.', ge=1)]
    height: Annotated[SchemaInt, Field(description='Screen height in pixels.', ge=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 height : int
var model_config
var width : int

Inherited members

class PublisherProperty1 (**data: Any)
Expand source code
class PublisherProperty1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com'). XOR with `publisher_domains` — exactly one MUST be present on each `publisher_properties[]` entry; both-present and neither-present both fail validation.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    publisher_domains: Annotated[
        list[PublisherDomain] | None,
        Field(
            description="Compact form for fanning the same selector across many publishers (e.g., a managed network listing every publisher it represents). Each entry is the domain where that publisher's adagents.json is hosted. Each listed domain MUST be canonicalized to lowercase (the `pattern` already rejects uppercase). Mutually exclusive with `publisher_domain`. Each listed domain counts as explicitly scoped for the `managerdomain` fallback safety rule.",
            min_length=1,
        ),
    ] = None
    selection_type: Annotated[
        Literal['all'],
        Field(
            description='Discriminator indicating all properties from each addressed publisher are included'
        ),
    ] = 'all'

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 model_config
var publisher_domain : str | None
var publisher_domains : list[PublisherDomain] | None
var selection_type : Literal['all']

Inherited members

class PublisherProperty2 (**data: Any)
Expand source code
class PublisherProperty2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com').",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    selection_type: Annotated[
        Literal['by_id'],
        Field(description='Discriminator indicating selection by specific property IDs'),
    ] = 'by_id'
    property_ids: Annotated[
        list[property_id.PropertyId],
        Field(description="Specific property IDs from the publisher's adagents.json", 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

Subclasses

Class variables

var model_config
var property_ids : list[PropertyId]
var publisher_domain : str
var selection_type : Literal['by_id']

Inherited members

class PublisherProperty3 (**data: Any)
Expand source code
class PublisherProperty3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com'). XOR with `publisher_domains` — exactly one MUST be present on each `publisher_properties[]` entry; both-present and neither-present both fail validation.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    publisher_domains: Annotated[
        list[PublisherDomain] | None,
        Field(
            description="Compact form for fanning the same tag predicate across many publishers (canonical managed-network shape). Each entry is the domain where that publisher's adagents.json is hosted. Each listed domain MUST be canonicalized to lowercase (the `pattern` already rejects uppercase). Mutually exclusive with `publisher_domain`. Each listed domain counts as explicitly scoped for the `managerdomain` fallback safety rule.",
            min_length=1,
        ),
    ] = None
    selection_type: Annotated[
        Literal['by_tag'], Field(description='Discriminator indicating selection by property tags')
    ] = 'by_tag'
    property_tags: Annotated[
        list[property_tag.PropertyTag],
        Field(
            description="Property tags resolved against each addressed publisher's adagents.json, OR against the parent file's top-level `properties[]` when those properties carry a `publisher_domain` matching the selector. Selector covers all properties carrying any of these tags.",
            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

Subclasses

Class variables

var model_config
var property_tags : list[PropertyTag]
var publisher_domain : str | None
var publisher_domains : list[PublisherDomain] | None
var selection_type : Literal['by_tag']

Inherited members

class PublisherProperty4 (**data: Any)
Expand source code
class PublisherProperty4(AdCPBaseModel):
    pass

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 model_config

Inherited members

class PublisherProperty5 (**data: Any)
Expand source code
class PublisherProperty5(PublisherProperty1, PublisherProperty4):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class PublisherProperty6 (**data: Any)
Expand source code
class PublisherProperty6(PublisherProperty2, PublisherProperty4):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class PublisherProperty7 (**data: Any)
Expand source code
class PublisherProperty7(PublisherProperty3, PublisherProperty4):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class PublisherProperty81 (**data: Any)
Expand source code
class PublisherProperty81(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com'). XOR with `publisher_domains` — exactly one MUST be present on each `publisher_properties[]` entry; both-present and neither-present both fail validation.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    publisher_domains: Annotated[
        list[PublisherDomain] | None,
        Field(
            description="Compact form for fanning the same selector across many publishers (e.g., a managed network listing every publisher it represents). Each entry is the domain where that publisher's adagents.json is hosted. Each listed domain MUST be canonicalized to lowercase (the `pattern` already rejects uppercase). Mutually exclusive with `publisher_domain`. Each listed domain counts as explicitly scoped for the `managerdomain` fallback safety rule.",
            min_length=1,
        ),
    ] = None
    selection_type: Annotated[
        Literal['all'],
        Field(
            description='Discriminator indicating all properties from each addressed publisher are included'
        ),
    ] = 'all'

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 model_config
var publisher_domain : str | None
var publisher_domains : list[PublisherDomain] | None
var selection_type : Literal['all']

Inherited members

class PublisherProperty82 (**data: Any)
Expand source code
class PublisherProperty82(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com').",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    selection_type: Annotated[
        Literal['by_id'],
        Field(description='Discriminator indicating selection by specific property IDs'),
    ] = 'by_id'
    property_ids: Annotated[
        list[property_id.PropertyId],
        Field(description="Specific property IDs from the publisher's adagents.json", 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

Subclasses

Class variables

var model_config
var property_ids : list[PropertyId]
var publisher_domain : str
var selection_type : Literal['by_id']

Inherited members

class PublisherProperty83 (**data: Any)
Expand source code
class PublisherProperty83(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com'). XOR with `publisher_domains` — exactly one MUST be present on each `publisher_properties[]` entry; both-present and neither-present both fail validation.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    publisher_domains: Annotated[
        list[PublisherDomain] | None,
        Field(
            description="Compact form for fanning the same tag predicate across many publishers (canonical managed-network shape). Each entry is the domain where that publisher's adagents.json is hosted. Each listed domain MUST be canonicalized to lowercase (the `pattern` already rejects uppercase). Mutually exclusive with `publisher_domain`. Each listed domain counts as explicitly scoped for the `managerdomain` fallback safety rule.",
            min_length=1,
        ),
    ] = None
    selection_type: Annotated[
        Literal['by_tag'], Field(description='Discriminator indicating selection by property tags')
    ] = 'by_tag'
    property_tags: Annotated[
        list[property_tag.PropertyTag],
        Field(
            description="Property tags resolved against each addressed publisher's adagents.json, OR against the parent file's top-level `properties[]` when those properties carry a `publisher_domain` matching the selector. Selector covers all properties carrying any of these tags.",
            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

Subclasses

Class variables

var model_config
var property_tags : list[PropertyTag]
var publisher_domain : str | None
var publisher_domains : list[PublisherDomain] | None
var selection_type : Literal['by_tag']

Inherited members

class PublisherProperty84 (**data: Any)
Expand source code
class PublisherProperty84(AdCPBaseModel):
    pass

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 model_config

Inherited members

class PublisherProperty85 (**data: Any)
Expand source code
class PublisherProperty85(PublisherProperty81, PublisherProperty84):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class PublisherProperty86 (**data: Any)
Expand source code
class PublisherProperty86(PublisherProperty82, PublisherProperty84):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class PublisherProperty87 (**data: Any)
Expand source code
class PublisherProperty87(PublisherProperty83, PublisherProperty84):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class PublisherPropertySelector1 (**data: Any)
Expand source code
class PublisherPropertySelector1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com'). XOR with `publisher_domains` — exactly one MUST be present on each `publisher_properties[]` entry; both-present and neither-present both fail validation.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    publisher_domains: Annotated[
        list[PublisherDomain] | None,
        Field(
            description="Compact form for fanning the same selector across many publishers (e.g., a managed network listing every publisher it represents). Each entry is the domain where that publisher's adagents.json is hosted. Each listed domain MUST be canonicalized to lowercase (the `pattern` already rejects uppercase). Mutually exclusive with `publisher_domain`. Each listed domain counts as explicitly scoped for the `managerdomain` fallback safety rule.",
            min_length=1,
        ),
    ] = None
    selection_type: Annotated[
        Literal['all'],
        Field(
            description='Discriminator indicating all properties from each addressed publisher are included'
        ),
    ] = 'all'

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var publisher_domain : str | None
var publisher_domains : list[PublisherDomain] | None
var selection_type : Literal['all']

Inherited members

class PublisherPropertySelector2 (**data: Any)
Expand source code
class PublisherPropertySelector2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com').",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    selection_type: Annotated[
        Literal['by_id'],
        Field(description='Discriminator indicating selection by specific property IDs'),
    ] = 'by_id'
    property_ids: Annotated[
        list[property_id.PropertyId],
        Field(description="Specific property IDs from the publisher's adagents.json", 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 model_config
var property_ids : list[PropertyId]
var publisher_domain : str
var selection_type : Literal['by_id']

Inherited members

class PublisherPropertySelector3 (**data: Any)
Expand source code
class PublisherPropertySelector3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    publisher_domain: Annotated[
        str | None,
        Field(
            description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com'). XOR with `publisher_domains` — exactly one MUST be present on each `publisher_properties[]` entry; both-present and neither-present both fail validation.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    publisher_domains: Annotated[
        list[PublisherDomain] | None,
        Field(
            description="Compact form for fanning the same tag predicate across many publishers (canonical managed-network shape). Each entry is the domain where that publisher's adagents.json is hosted. Each listed domain MUST be canonicalized to lowercase (the `pattern` already rejects uppercase). Mutually exclusive with `publisher_domain`. Each listed domain counts as explicitly scoped for the `managerdomain` fallback safety rule.",
            min_length=1,
        ),
    ] = None
    selection_type: Annotated[
        Literal['by_tag'], Field(description='Discriminator indicating selection by property tags')
    ] = 'by_tag'
    property_tags: Annotated[
        list[property_tag.PropertyTag],
        Field(
            description="Property tags resolved against each addressed publisher's adagents.json, OR against the parent file's top-level `properties[]` when those properties carry a `publisher_domain` matching the selector. Selector covers all properties carrying any of these tags.",
            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 model_config
var property_tags : list[PropertyTag]
var publisher_domain : str | None
var publisher_domains : list[PublisherDomain] | None
var selection_type : Literal['by_tag']

Inherited members

class PushNotificationConfig (**data: Any)
Expand source code
class PushNotificationConfig(AdCPBaseModel):
    url: Annotated[
        AnyUrl,
        Field(
            description='Webhook endpoint URL for task status notifications. The wire contract is unconstrained beyond `format: "uri"` — in particular, publishers SHOULD NOT enforce a destination-port allowlist by default, since buyers legitimately host receivers on non-standard TLS ports (`:9443`, `:4443`, path-routed multi-tenant gateways). The SSRF guard the protocol relies on is the IP-range check + DNS-rebinding-resistant connect pin defined in [Webhook URL validation (SSRF)](/docs/building/by-layer/L1/security#webhook-url-validation-ssrf), not port filtering. Operators who want a hardened destination-port allowlist as defense-in-depth (e.g., locked-down enterprise egress) opt in explicitly — see [Destination port: permissive by default](/docs/building/by-layer/L1/security#destination-port-permissive-by-default).'
        ),
    ]
    operation_id: Annotated[
        str | None,
        Field(
            description="Buyer-supplied correlation identifier for the operation that will produce webhooks against this registration. The seller MUST echo this value verbatim into every webhook payload's `operation_id` field (see [`mcp-webhook-payload.json`](/schemas/core/mcp-webhook-payload.json) and [Webhooks — Operation IDs](/docs/building/by-layer/L3/webhooks#operation-ids-and-url-templates)). Buyers SHOULD generate a unique value per task invocation (UUID recommended). This field is the canonical registration channel for `operation_id`; buyers MAY additionally embed routing values in the URL path or query as an aid for their own HTTP server, but the URL is opaque to the seller and the wire-level source of truth is this field. Sellers MUST NOT parse the URL to recover `operation_id`. For 3.x schema compatibility the member remains optional, but a seller MUST reject a task that registers an AdCP webhook without it using `INVALID_REQUEST`; otherwise the required webhook envelope cannot be emitted.",
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    token: Annotated[
        str | None,
        Field(
            description="Optional client-provided token for webhook validation. The seller MUST echo this value verbatim in every webhook payload's `token` field (see [`mcp-webhook-payload.json`](/schemas/core/mcp-webhook-payload.json) for the receiver-side validation obligation). Length bounds give receivers a defensive range check on the echoed value; senders SHOULD generate tokens with at least 128 bits of entropy (≥22 base64url characters). This is a complementary authenticity mechanism that can layer on top of the RFC 9421 webhook signature — unlike the `authentication` block below, it is not on the 4.0 removal track. Receivers that registered both a signing key (RFC 9421) and a `token` MUST NOT treat a valid token echo as authorization to skip signature verification; both checks remain independent obligations.",
            max_length=4096,
            min_length=16,
        ),
    ] = None
    authentication: Annotated[
        Authentication | None,
        Field(
            deprecated=True,
            description='Legacy authentication configuration (A2A-compatible). Opts the seller into Bearer or HMAC-SHA256 signing instead of the default RFC 9421 webhook profile. Deprecated; removed in AdCP 4.0. **Precedence is a switch, not a fallback:** presence of this block selects the legacy scheme; absence selects 9421. A seller MUST NOT sign the same webhook both ways, and a buyer MUST NOT attempt \'try 9421 first, fall back to HMAC\' verification — signature mode is determined solely by whether this block was present at registration time. The seller\'s baseline 9421 webhook key is published at its brand.json `agents[]` `jwks_uri` using `adcp_use: "request-signing"` (deprecated `webhook-signing` keys remain accepted during the compatibility window); it does not override this selector and is only used when `authentication` is omitted. See docs/building/by-layer/L1/security.mdx#webhook-callbacks for the full precedence and downgrade-resistance rules (including the `webhook_mode_mismatch` rejection a buyer MUST apply when a received webhook\'s signing mode does not match the registered mode).',
        ),
    ] = 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 authentication : Authentication | None
var model_config
var operation_id : str | None
var token : str | None
var url : pydantic.networks.AnyUrl

Inherited members

class Qualifier1 (**data: Any)
Expand source code
class Qualifier1(Qualifier):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Qualifier3 (**data: Any)
Expand source code
class Qualifier3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    viewability_standard: Annotated[
        viewability_standard_1.ViewabilityStandard | None,
        Field(
            description='Viewability standard under which this row was measured. MRC and GroupM define materially different thresholds; never sum across standards.'
        ),
    ] = None
    completion_source: Annotated[
        completion_source_1.CompletionSource | None,
        Field(
            description='Attestation source for a vendor completion-style metric — seller_attested from player/ad server, vendor_attested from an independent measurement path. Applicability is defined by the vendor metric; never sum across sources.'
        ),
    ] = None
    attribution_methodology: Annotated[
        attribution_methodology_1.AttributionMethodology | None,
        Field(
            description='Attribution methodology under which this outcome row was computed (`deterministic_purchase`, `probabilistic`, `panel_based`, `modeled`). Outcome metrics measured under different methodologies represent materially different numbers; never sum across methodologies.'
        ),
    ] = None
    attribution_window: Annotated[
        duration.Duration | None,
        Field(
            description="Attribution window for this outcome row. Object-valued duration (`{interval, unit}`), not a shorthand string. Outcome metrics measured over different windows represent the same metric over different time periods; the partition keeps them as separate rows so buyers don't accidentally aggregate."
        ),
    ] = None
    lift_dimension: Annotated[
        lift_dimension_1.LiftDimension | None,
        Field(
            description='Lift dimension this row represents (awareness, consideration, favorability, purchase intent, or ad recall) for vendor lift-style metrics. Applicability is defined by the vendor metric; each dimension is a separate surveyed outcome and rows under different dimensions must not be summed.'
        ),
    ] = 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 attribution_methodology : AttributionMethodology | None
var attribution_window : Duration | None
var completion_source : CompletionSource | None
var lift_dimension : LiftDimension | None
var model_config
var viewability_standard : ViewabilityStandard | None

Inherited members

class QualifierModel (**data: Any)
Expand source code
class QualifierModel(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    viewability_standard: Annotated[
        viewability_standard_1.ViewabilityStandard | None,
        Field(
            description='Viewability standard the seller commits to for this metric. MUST be set when `metric_id` ∈ {`viewable_impressions`, `viewable_rate`, `measurable_impressions`, `viewed_seconds`, `viewed_seconds_percentiles`, `viewed_seconds_histogram`} and the seller commits to a specific standard; absence means the contract leaves the standard unspecified and reconciliation falls back to whatever standard the delivery report carries on its `viewability.standard` field. A distribution whose standard remains unspecified MUST NOT be combined with any other row, including another row with an unspecified standard.'
        ),
    ] = None
    completion_source: Annotated[
        completion_source_1.CompletionSource | None,
        Field(
            description="Source of `completion_rate` attestation. MUST be set when `metric_id` is `completion_rate` and the seller commits to a specific source — `seller_attested` when the player/ad server's own completion event is the contract, `vendor_attested` when a third-party measurement vendor (anchored on the matching `performance_standard.vendor` BrandRef) is the contract. Absence means the contract leaves the source unspecified and reconciliation falls back to whatever the delivery report happens to carry."
        ),
    ] = None
    attribution_methodology: Annotated[
        attribution_methodology_1.AttributionMethodology | None,
        Field(
            description='How attribution between ad exposure and outcome events was computed. SHOULD be set when `metric_id` is an outcome metric (`conversions`, `conversion_value`, `roas`, `cost_per_acquisition`, `incremental_sales_lift`, `brand_lift`, `foot_traffic`, `conversion_lift`, `brand_search_lift`, `units_sold`, `new_to_brand_rate`, `new_to_brand_units`, `leads`) and the seller commits to a specific methodology. `deterministic_purchase` is the retail-media default; `modeled` covers MMM and clean-room outputs; `probabilistic` and `panel_based` cover their respective methodologies. Two outcome rows with the same `metric_id` and different `attribution_methodology` are not interchangeable and must not be summed.'
        ),
    ] = None
    attribution_window: Annotated[
        duration.Duration | None,
        Field(
            description="Time window over which outcome attribution is computed. **Object-valued, not string** — MUST be a structured duration object like `{interval: 14, unit: 'days'}`, NEVER a shorthand string like `'14d'`. SHOULD be set when `metric_id` is an outcome metric and the seller commits to a specific window. Common windows: `{interval: 7, unit: 'days'}`, `{interval: 14, unit: 'days'}`, `{interval: 30, unit: 'days'}`, `{interval: 90, unit: 'days'}`. Two outcome rows with the same `metric_id` and `attribution_methodology` but different `attribution_window` represent the same metric measured over different periods — the join on `(metric_id, qualifier)` keeps them as separate rows so buyers don't accidentally aggregate across windows."
        ),
    ] = None
    lift_dimension: Annotated[
        lift_dimension_1.LiftDimension | None,
        Field(
            description='Which dimension of `brand_lift` this row represents — awareness, consideration, favorability, purchase intent, or ad recall. MUST be set when `metric_id` is `brand_lift` and the seller commits to (or is reporting) a specific dimension. Brand-lift vendors (Kantar, Upwave, Cint, DoubleVerify) report each dimension separately with its own sample size and confidence interval; combining them into a single number is a category error. Two `brand_lift` rows under different `lift_dimension` are different surveyed outcomes and must not be summed.'
        ),
    ] = 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 attribution_methodology : AttributionMethodology | None
var attribution_window : Duration | None
var completion_source : CompletionSource | None
var lift_dimension : LiftDimension | None
var model_config
var viewability_standard : ViewabilityStandard | None

Inherited members

class QuartileData (**data: Any)
Expand source code
class QuartileData(AdCPBaseModel):
    q1_views: Annotated[StrictFloat | None, Field(description='25% completion views', ge=0.0)] = (
        None
    )
    q2_views: Annotated[StrictFloat | None, Field(description='50% completion views', ge=0.0)] = (
        None
    )
    q3_views: Annotated[StrictFloat | None, Field(description='75% completion views', ge=0.0)] = (
        None
    )
    q4_views: Annotated[StrictFloat | None, Field(description='100% completion views', ge=0.0)] = (
        None
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var q1_views : float | None
var q2_views : float | None
var q3_views : float | None
var q4_views : float | None

Inherited members

class QuerySummary (**data: Any)
Expand source code
class QuerySummary(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    total_matching: Annotated[
        SchemaInt | None,
        Field(description='Total number of tasks matching filters (across all pages)', ge=0),
    ] = None
    returned: Annotated[
        SchemaInt | None, Field(description='Number of tasks returned in this response', ge=0)
    ] = None
    domain_breakdown: Annotated[
        DomainBreakdown | None, Field(description='Count of tasks by domain')
    ] = None
    status_breakdown: Annotated[
        dict[str, SchemaInt] | None, Field(description='Count of tasks by status')
    ] = None
    filters_applied: Annotated[
        list[str] | None, Field(description='List of filters that were applied to the query')
    ] = None
    sort_applied: Annotated[
        SortApplied | None, Field(description='Sort order that was applied')
    ] = 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 domain_breakdown : DomainBreakdown | None
var filters_applied : list[str] | None
var model_config
var returned : int | None
var sort_applied : SortApplied | None
var status_breakdown : dict[str, int] | None
var total_matching : int | None

Inherited members

class RankByItem (**data: Any)
Expand source code
class RankByItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    feature_id: Annotated[
        str,
        Field(
            description='Creative feature to order by (discovered via get_adcp_capabilities; the same feature_id space the chosen evaluator form returns in eval.features[]).'
        ),
    ]
    direction: Annotated[
        Direction | None,
        Field(
            description='Sort direction for this feature: `maximize` ranks higher feature values first (e.g. creative_quality_score), `minimize` ranks lower values first (e.g. predicted_cpa).'
        ),
    ] = Direction.maximize

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 direction : Direction | None
var feature_id : str
var model_config

Inherited members

class RankByItem1 (**data: Any)
Expand source code
class RankByItem1(RankByItem):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class RankByItem2 (**data: Any)
Expand source code
class RankByItem2(RankByItem):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class ReachWindow (**data: Any)
Expand source code
class ReachWindow(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Annotated[
        Kind,
        Field(
            description="Window semantics. `cumulative` — uniques since campaign start; the value is the total unique count to date and MUST NOT be summed across rows (each later row supersedes the earlier value). `period` — uniques within a single non-overlapping reporting period (e.g., a daily snapshot for a specific calendar day). Adjacent `period` rows do not share audiences by construction, but the same person MAY appear across multiple periods, so MUST NOT be summed across rows to compute campaign reach. `rolling` — uniques within a trailing window ending at the row's reporting timestamp (e.g., trailing-7-day reach). Adjacent rolling rows overlap and MUST NOT be summed; each row's value stands alone."
        ),
    ]
    period: Annotated[
        duration.Duration | None,
        Field(
            description='Duration of the measurement window. REQUIRED when `kind` is `period` or `rolling` — declares the snapshot length (e.g., `{"interval": 1, "unit": "days"}` for a daily snapshot) or the trailing-window length (e.g., `{"interval": 7, "unit": "days"}` for trailing-7-day rolling reach). When `kind` is `cumulative`, this field is implicit (campaign-to-date) and SHOULD be omitted.'
        ),
    ] = 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 kind : Kind
var model_config
var period : Duration | None

Inherited members

class Readiness (*args, **kwds)
Expand source code
class Readiness(StrEnum):
    available = 'available'
    delivered = 'delivered'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var available
var delivered
class RealEstateItem (**data: Any)
Expand source code
class RealEstateItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    listing_id: Annotated[str, Field(description='Unique identifier for this property listing.')]
    title: Annotated[
        str, Field(description="Listing title (e.g., 'Spacious 3BR Apartment in Jordaan').")
    ]
    address: Annotated[Address, Field(description='Property address.')]
    price: Annotated[
        price_1.Price | None,
        Field(description="Property price or rental rate. Use period 'month' for rentals."),
    ] = None
    property_type: Annotated[PropertyType | None, Field(description='Type of property.')] = None
    listing_type: Annotated[
        ListingType | None, Field(description='Whether the property is for sale or rent.')
    ] = None
    bedrooms: Annotated[SchemaInt | None, Field(description='Number of bedrooms.', ge=0)] = None
    bathrooms: Annotated[
        StrictFloat | None,
        Field(
            description='Number of bathrooms (e.g., 2.5 for two full and one half bath).', ge=0.0
        ),
    ] = None
    area: Annotated[Area | None, Field(description='Property size.')] = None
    description: Annotated[str | None, Field(description='Property description.')] = None
    location: Annotated[
        Location | None, Field(description='Geographic coordinates of the property.')
    ] = None
    image_url: Annotated[AnyUrl | None, Field(description='Primary property image URL.')] = None
    url: Annotated[AnyUrl | None, Field(description='Listing page URL.')] = None
    neighborhood: Annotated[str | None, Field(description='Neighborhood or area name.')] = None
    year_built: Annotated[SchemaInt | None, Field(description='Year the property was built.')] = (
        None
    )
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering (e.g., 'garden', 'parking', 'renovated', 'waterfront').",
            min_length=1,
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this property listing. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (exterior/interior hero), 'images_vertical' (9:16 for Stories), 'images_square' (1:1). Enables formats to declare typed image requirements that map unambiguously to the right asset regardless of platform.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 address : Address
var area : Area | None
var assets : list[OfferingAssetGroup] | None
var bathrooms : float | None
var bedrooms : int | None
var description : str | None
var ext : ExtensionObject | None
var image_url : pydantic.networks.AnyUrl | None
var listing_id : str
var listing_type : ListingType | None
var location : Location | None
var model_config
var neighborhood : str | None
var price : Price | None
var property_type : PropertyType | None
var tags : list[str] | None
var title : str
var url : pydantic.networks.AnyUrl | None
var year_built : int | None

Inherited members

class Recipient (**data: Any)
Expand source code
class Recipient(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    identity: Annotated[str, Field(max_length=512, min_length=1)]
    cloud: ReportingCloud | None = None
    region: Annotated[str | None, Field(max_length=128, min_length=1)] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var cloud : ReportingCloud | None
var identity : str
var model_config
var region : str | None

Inherited members

class RecommendedAction (*args, **kwds)
Expand source code
class RecommendedAction(StrEnum):
    wait_for_retry = 'wait_for_retry'
    contact_buyer = 'contact_buyer'
    contact_seller = 'contact_seller'
    contact_provider = 'contact_provider'
    repair_access = 'repair_access'
    update_configuration = 'update_configuration'
    change_reporting_scope = 'change_reporting_scope'
    use_supported_reader = 'use_supported_reader'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var change_reporting_scope
var contact_buyer
var contact_provider
var contact_seller
var repair_access
var update_configuration
var use_supported_reader
var wait_for_retry
class ReconciliationStatus (*args, **kwds)
Expand source code
class ReconciliationStatus(StrEnum):
    not_required = 'not_required'
    pending = 'pending'
    accepted = 'accepted'
    rejected = 'rejected'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var accepted
var not_required
var pending
var rejected
class Recovery (*args, **kwds)
Expand source code
class Recovery(StrEnum):
    transient = 'transient'
    correctable = 'correctable'
    terminal = 'terminal'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var correctable
var terminal
var transient
class Rectangle (**data: Any)
Expand source code
class Rectangle(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    x: Annotated[SchemaInt, Field(ge=0, le=8192)]
    y: Annotated[SchemaInt, Field(ge=0, le=8192)]
    width: Annotated[SchemaInt, Field(ge=1, le=8192)]
    height: Annotated[SchemaInt, Field(ge=1, le=8192)]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var height : int
var model_config
var width : int
var x : int
var y : int

Inherited members

class Reference (**data: Any)
Expand source code
class Reference(AttestationReference):
    issuer: Annotated[
        Issuer | Issuer5 | Issuer6 | None,
        Field(
            description='Canonical identity of the party that issued an attestation credential. The discriminator selects an existing AdCP identity when one exists and falls back to an HTTPS origin for other attestors. This identity is a claim carried by the presentation; evaluators MUST match it against their configured trust policy and verify it from the resolved or embedded credential before relying on it.',
            discriminator='type',
            examples=[
                {
                    'type': 'brand',
                    'brand': {'domain': 'nova-brands.example', 'brand_id': 'nova_motors'},
                },
                {'type': 'agent', 'agent_url': 'https://attestor.example/adcp'},
                {'type': 'origin', 'origin': 'https://credentials.example'},
            ],
            title='Attestation Issuer',
        ),
    ] = None
    claim_type: Annotated[
        Literal['https://adcontextprotocol.org/claims/rights/grant'],
        Field(
            description='Open, absolute URI identifying the claim vocabulary. The URI is an identifier and need not be dereferenceable. AdCP does not maintain an enum of approved claims.'
        ),
    ] = 'https://adcontextprotocol.org/claims/rights/grant'
    subject: Annotated[
        Subject10 | Subject | Subject19 | None,
        Field(
            description='Typed identity of the entity or object an attestation credential is about. Brand and agent subjects reuse canonical AdCP identities. Other resources use an open, URI-namespaced resource_type plus an identifier whose namespace is explicit. Evaluators MUST compare the resolved credential subject to this complete typed identity, not to id alone.',
            discriminator='type',
            examples=[
                {
                    'type': 'brand',
                    'brand': {'domain': 'nova-brands.example', 'brand_id': 'nova_motors'},
                },
                {
                    'type': 'resource',
                    'resource_type': 'https://adcontextprotocol.org/claims/subjects/signal',
                    'namespace': 'https://signals.meridian.example/adcp',
                    'id': 'signal_urban_commuters',
                },
            ],
            title='Attestation Subject',
        ),
    ] = 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 claim_type : Literal['https://adcontextprotocol.org/claims/rights/grant']
var issuer : Issuer | Issuer5 | Issuer6 | None
var model_config
var subject : Subject10 | Subject | Subject19 | None

Inherited members

class ReferenceAuthorization1 (**data: Any)
Expand source code
class ReferenceAuthorization1(ReferenceAuthorization):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class ReferenceRenderer (**data: Any)
Expand source code
class ReferenceRenderer(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    runtime: Annotated[
        Literal['browser-esm'],
        Field(
            description='Execution contract for the referenced package. browser-esm means a browser-safe ECMAScript module that accepts canonical manifest data and returns an inert presentation without Node.js APIs, ambient credentials, delivery tracking, or undeclared network access. Non-JavaScript clients use a hosted preview_creative provider or display the manifest.'
        ),
    ] = 'browser-esm'
    package: Annotated[
        str,
        Field(
            description='npm package name, scoped or unscoped. The package is resolved from the npm registry; the AdCP registry does not proxy its executable contents.',
            pattern='^(?:@[a-z0-9][a-z0-9._~-]*/)?[a-z0-9][a-z0-9._~-]*$',
        ),
    ]
    version: Annotated[
        str,
        Field(
            description='Exact semantic version. Ranges and tags such as latest are forbidden so the registry entry is reproducible. Package semantic versioning identifies the pinned distribution artifact; it is independent of any one format revision because one package may expose renderers for multiple formats.',
            pattern='^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$',
        ),
    ]
    export: Annotated[
        str,
        Field(
            description="Named package export that implements the renderer contract for this enclosing format entry. Compatibility is bound at the export-to-entry edge, not to matching version labels: registry review and contract fixtures verify that the export implements the entry's input contract. When that input contract changes, the registry MUST rerun those fixtures and MAY retain the existing export and package pin when they still pass. One package version MAY expose different named exports for different formats or input contracts.",
            min_length=1,
        ),
    ]
    format_revision: Annotated[
        str | None,
        Field(
            deprecated=True,
            description="Deprecated compatibility annotation retained for previously published registry entries. Renderer package versions and community format revisions have independent lifecycles, so consumers MUST NOT require this value to equal the enclosing entry's format_revision or use matching values as evidence of compatibility. Registry review and contract fixtures bind the named export to the enclosing format's input contract. New entries SHOULD omit this field.",
            pattern='^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$',
        ),
    ] = None
    integrity: Annotated[
        str,
        Field(
            description='Subresource Integrity value for the exact npm package tarball. Consumers MUST compare this value before loading code, require the provenance subject digest to match the same tarball, and fail closed on mismatch.',
            pattern='^(?:sha256-[A-Za-z0-9+/]{43}=|sha384-[A-Za-z0-9+/]{64}|sha512-[A-Za-z0-9+/]{86}==)$',
        ),
    ]
    provenance: Provenance

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var export : str
var format_revision : str | None
var integrity : str
var model_config
var package : str
var provenance : Provenance
var runtime : Literal['browser-esm']
var version : str

Inherited members

class RefineProposalsInputRequired (**data: Any)
Expand source code
class RefineProposalsInputRequired(CompactTaskInputRequired):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class RefineProposalsSubmitted (**data: Any)
Expand source code
class RefineProposalsSubmitted(CompactTaskSubmitted):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class RefineProposalsWorking (**data: Any)
Expand source code
class RefineProposalsWorking(CompactTaskWorking):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class RegistryEvent1 (**data: Any)
Expand source code
class RegistryEvent1(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['property.created'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'property.created'
    entity_type: Annotated[
        Literal['property'], Field(description='Entity class touched by this event.')
    ] = 'property'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        PropertyPayload,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.property']
var event_id : uuid.UUID
var event_type : Literal['property.created']
var model_config
var payload : PropertyPayload

Inherited members

class RegistryEvent10 (**data: Any)
Expand source code
class RegistryEvent10(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['agent.discovered'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'agent.discovered'
    entity_type: Annotated[
        Literal['agent'], Field(description='Entity class touched by this event.')
    ] = 'agent'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        AgentProfilePayload,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['agent']
var event_id : uuid.UUID
var event_type : Literal['agent.discovered']
var model_config
var payload : AgentProfilePayload

Inherited members

class RegistryEvent11 (**data: Any)
Expand source code
class RegistryEvent11(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['agent.removed'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'agent.removed'
    entity_type: Annotated[
        Literal['agent'], Field(description='Entity class touched by this event.')
    ] = 'agent'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload5,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['agent']
var event_id : uuid.UUID
var event_type : Literal['agent.removed']
var model_config
var payload : Payload5

Inherited members

class RegistryEvent12 (**data: Any)
Expand source code
class RegistryEvent12(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['agent.profile_updated'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'agent.profile_updated'
    entity_type: Annotated[
        Literal['agent'], Field(description='Entity class touched by this event.')
    ] = 'agent'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload6,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['agent']
var event_id : uuid.UUID
var event_type : Literal['agent.profile_updated']
var model_config
var payload : Payload6

Inherited members

class RegistryEvent13 (**data: Any)
Expand source code
class RegistryEvent13(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['agent.compliance_changed'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'agent.compliance_changed'
    entity_type: Annotated[
        Literal['agent'], Field(description='Entity class touched by this event.')
    ] = 'agent'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload7,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['agent']
var event_id : uuid.UUID
var event_type : Literal['agent.compliance_changed']
var model_config
var payload : Payload7

Inherited members

class RegistryEvent14 (**data: Any)
Expand source code
class RegistryEvent14(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['agent.verification_earned'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'agent.verification_earned'
    entity_type: Annotated[
        Literal['agent'], Field(description='Entity class touched by this event.')
    ] = 'agent'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload8,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['agent']
var event_id : uuid.UUID
var event_type : Literal['agent.verification_earned']
var model_config
var payload : Payload8

Inherited members

class RegistryEvent15 (**data: Any)
Expand source code
class RegistryEvent15(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['agent.verification_lost'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'agent.verification_lost'
    entity_type: Annotated[
        Literal['agent'], Field(description='Entity class touched by this event.')
    ] = 'agent'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload9,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['agent']
var event_id : uuid.UUID
var event_type : Literal['agent.verification_lost']
var model_config
var payload : Payload9

Inherited members

class RegistryEvent16 (**data: Any)
Expand source code
class RegistryEvent16(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['publisher.adagents_discovered'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'publisher.adagents_discovered'
    entity_type: Annotated[
        Literal['publisher'], Field(description='Entity class touched by this event.')
    ] = 'publisher'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload10,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['publisher']
var event_id : uuid.UUID
var event_type : Literal['publisher.adagents_discovered']
var model_config
var payload : Payload10

Inherited members

class RegistryEvent17 (**data: Any)
Expand source code
class RegistryEvent17(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['publisher.adagents_changed'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'publisher.adagents_changed'
    entity_type: Annotated[
        Literal['publisher'], Field(description='Entity class touched by this event.')
    ] = 'publisher'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload11,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['publisher']
var event_id : uuid.UUID
var event_type : Literal['publisher.adagents_changed']
var model_config
var payload : Payload11

Inherited members

class RegistryEvent18 (**data: Any)
Expand source code
class RegistryEvent18(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['authorization.granted'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'authorization.granted'
    entity_type: Annotated[
        Literal['authorization'], Field(description='Entity class touched by this event.')
    ] = 'authorization'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload12,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['authorization']
var event_id : uuid.UUID
var event_type : Literal['authorization.granted']
var model_config
var payload : Payload12

Inherited members

class RegistryEvent19 (**data: Any)
Expand source code
class RegistryEvent19(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['authorization.revoked'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'authorization.revoked'
    entity_type: Annotated[
        Literal['authorization'], Field(description='Entity class touched by this event.')
    ] = 'authorization'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload13,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['authorization']
var event_id : uuid.UUID
var event_type : Literal['authorization.revoked']
var model_config
var payload : Payload13

Inherited members

class RegistryEvent2 (**data: Any)
Expand source code
class RegistryEvent2(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['property.updated'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'property.updated'
    entity_type: Annotated[
        Literal['property'], Field(description='Entity class touched by this event.')
    ] = 'property'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        PropertyPayload,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.property']
var event_id : uuid.UUID
var event_type : Literal['property.updated']
var model_config
var payload : PropertyPayload

Inherited members

class RegistryEvent20 (**data: Any)
Expand source code
class RegistryEvent20(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['authorization.modified'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'authorization.modified'
    entity_type: Annotated[
        Literal['authorization'], Field(description='Entity class touched by this event.')
    ] = 'authorization'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload14,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['authorization']
var event_id : uuid.UUID
var event_type : Literal['authorization.modified']
var model_config
var payload : Payload14

Inherited members

class RegistryEvent3 (**data: Any)
Expand source code
class RegistryEvent3(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['property.merged'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'property.merged'
    entity_type: Annotated[
        Literal['property'], Field(description='Entity class touched by this event.')
    ] = 'property'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.property']
var event_id : uuid.UUID
var event_type : Literal['property.merged']
var model_config
var payload : Payload

Inherited members

class RegistryEvent4 (**data: Any)
Expand source code
class RegistryEvent4(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['property.stale'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'property.stale'
    entity_type: Annotated[
        Literal['property'], Field(description='Entity class touched by this event.')
    ] = 'property'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload1,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.property']
var event_id : uuid.UUID
var event_type : Literal['property.stale']
var model_config
var payload : Payload1

Inherited members

class RegistryEvent5 (**data: Any)
Expand source code
class RegistryEvent5(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['property.reactivated'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'property.reactivated'
    entity_type: Annotated[
        Literal['property'], Field(description='Entity class touched by this event.')
    ] = 'property'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload2,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.property']
var event_id : uuid.UUID
var event_type : Literal['property.reactivated']
var model_config
var payload : Payload2

Inherited members

class RegistryEvent6 (**data: Any)
Expand source code
class RegistryEvent6(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['collection.created'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'collection.created'
    entity_type: Annotated[
        Literal['collection'], Field(description='Entity class touched by this event.')
    ] = 'collection'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        CollectionPayload,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.collection']
var event_id : uuid.UUID
var event_type : Literal['collection.created']
var model_config
var payload : CollectionPayload

Inherited members

class RegistryEvent7 (**data: Any)
Expand source code
class RegistryEvent7(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['collection.updated'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'collection.updated'
    entity_type: Annotated[
        Literal['collection'], Field(description='Entity class touched by this event.')
    ] = 'collection'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        CollectionPayload,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.collection']
var event_id : uuid.UUID
var event_type : Literal['collection.updated']
var model_config
var payload : CollectionPayload

Inherited members

class RegistryEvent8 (**data: Any)
Expand source code
class RegistryEvent8(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['collection.merged'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'collection.merged'
    entity_type: Annotated[
        Literal['collection'], Field(description='Entity class touched by this event.')
    ] = 'collection'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload3,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.collection']
var event_id : uuid.UUID
var event_type : Literal['collection.merged']
var model_config
var payload : Payload3

Inherited members

class RegistryEvent9 (**data: Any)
Expand source code
class RegistryEvent9(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier and feed cursor. UUID v7 is REQUIRED so consumers can apply events in event_id order without relying on producer clocks.'
        ),
    ]
    event_type: Annotated[
        Literal['collection.removed'],
        Field(description='Discriminator. Determines the shape of payload.'),
    ] = 'collection.removed'
    entity_type: Annotated[
        Literal['collection'], Field(description='Entity class touched by this event.')
    ] = 'collection'
    entity_id: Annotated[
        str,
        Field(
            description='Primary identifier for the changed entity. For property.* events this is the property_rid; for agent.* events this is the agent_url; for publisher.adagents_changed this is the publisher domain; for authorization.* events this is the authorization row id or a stable agent/publisher composite.'
        ),
    ]
    payload: Annotated[
        Payload4,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]
    actor: Annotated[
        str,
        Field(
            description='Internal producer label for audit and debugging, such as pipeline:crawler or trigger:caa_emit_event. Consumers MUST treat this as informational and not as an authorization principal.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the registry emitted the event. Advisory only; consumers MUST order and cursor by event_id.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var actor : str
var created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.collection']
var event_id : uuid.UUID
var event_type : Literal['collection.removed']
var model_config
var payload : Payload4

Inherited members

class RegistryFeedResponse (**data: Any)
Expand source code
class RegistryFeedResponse(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    events: list[registry_event.RegistryEvent]
    cursor: Annotated[
        UUID | None,
        Field(
            description='Pass this value as cursor on the next request to continue polling. Null only when the feed has no events and no prior cursor.'
        ),
    ]
    has_more: Annotated[
        StrictBool,
        Field(description='True when more events are immediately available after cursor.'),
    ]
    freshness: Annotated[
        Freshness,
        Field(
            description='Consumer-visible feed freshness metadata for the requested type filter.'
        ),
    ]

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 cursor : uuid.UUID | None
var events : list[RegistryEvent1 | RegistryEvent2 | RegistryEvent3 | RegistryEvent4 | RegistryEvent5 | RegistryEvent6 | RegistryEvent7 | RegistryEvent8 | RegistryEvent9 | RegistryEvent10 | RegistryEvent11 | RegistryEvent12 | RegistryEvent13 | RegistryEvent14 | RegistryEvent15 | RegistryEvent16 | RegistryEvent17 | RegistryEvent18 | RegistryEvent19 | RegistryEvent20]
var freshness : Freshness
var has_more : bool
var model_config

Inherited members

class RejectionCode (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class RejectionCode(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 128, 'min_length': 1, 'pattern': '^[A-Z][A-Z0-9_]*$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class RelatedCollection (**data: Any)
Expand source code
class RelatedCollection(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    collection_id: Annotated[
        str,
        Field(description="The related collection's collection_id within this seller's response"),
    ]
    relationship: Annotated[
        collection_relationship.CollectionRelationship,
        Field(description='How the collections are related'),
    ]

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 collection_id : str
var model_config
var relationship : CollectionRelationship

Inherited members

class RelationshipKind (*args, **kwds)
Expand source code
class RelationshipKind(StrEnum):
    media_buy = 'media_buy'
    package = 'package'
    creative_assignment = 'creative_assignment'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var creative_assignment
var media_buy
var package
class RemovalReason (*args, **kwds)
Expand source code
class RemovalReason(StrEnum):
    withdrawn = 'withdrawn'
    cancellation = 'cancellation'
    expired = 'expired'
    depublication = 'depublication'
    policy_takedown = 'policy_takedown'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var cancellation
var depublication
var expired
var policy_takedown
var withdrawn
class RenderingOrigin (*args, **kwds)
Expand source code
class RenderingOrigin(StrEnum):
    platform_native = 'platform_native'
    agent_approximation = 'agent_approximation'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var agent_approximation
var platform_native
class Renders (**data: Any)
Expand source code
class Renders(AdCPBaseModel):
    role: Annotated[
        str,
        Field(
            description="Semantic role of this rendered piece (e.g., 'primary', 'companion', 'mobile_variant')"
        ),
    ]
    parameters_from_format_id: Annotated[
        StrictBool | None,
        Field(
            description='When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly.'
        ),
    ] = None
    dimensions: Annotated[
        Dimensions,
        Field(
            description='Dimensions for this rendered piece. Defaults to pixels when unit is absent.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var dimensions : Dimensions
var model_config
var parameters_from_format_id : bool | None
var role : str

Inherited members

class Renders1 (**data: Any)
Expand source code
class Renders1(AdCPBaseModel):
    role: Annotated[
        str,
        Field(
            description="Semantic role of this rendered piece (e.g., 'primary', 'companion', 'mobile_variant')"
        ),
    ]
    parameters_from_format_id: Annotated[
        Literal[True],
        Field(
            description='When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly.'
        ),
    ]
    dimensions: Annotated[
        Dimensions1 | None,
        Field(
            description='Dimensions for this rendered piece. Defaults to pixels when unit is absent.'
        ),
    ] = 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 dimensions : Dimensions1 | None
var model_config
var parameters_from_format_id : Literal[True]
var role : str

Inherited members

class Repair (**data: Any)
Expand source code
class Repair(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    task: Annotated[
        Task,
        Field(
            description='Allowlisted authoritative read task. This is a repair hint, never an instruction to dispatch dynamically. The buyer constructs and validates the request locally from the authenticated feed account and resource identity.'
        ),
    ]
    available: Annotated[
        StrictBool | None,
        Field(
            description='False when deletion or compelled erasure makes the resource unavailable on the repair read.'
        ),
    ] = True
    unavailable_reason: UnavailableReason | 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 available : bool | None
var model_config
var task : Task
var unavailable_reason : UnavailableReason | None

Inherited members

class ReplacedByValue (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReplacedByValue(ParentLabel):
    pass

A str generated from a JSON Schema string root.

Ancestors

  • ParentLabel
  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportCalendarTimezoneBasis (*args, **kwds)
Expand source code
class ReportCalendarTimezoneBasis(StrEnum):
    utc = 'utc'
    account_timezone = 'account_timezone'
    schedule_timezone = 'schedule_timezone'
    configured_timezone = 'configured_timezone'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var account_timezone
var configured_timezone
var schedule_timezone
var utc
class ReportingAdjustment (**data: Any)
Expand source code
class ReportingAdjustment(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    reporting_adjustment_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    adjusts_reporting_revision_id: Annotated[
        str,
        Field(
            description='Exact immutable official revision whose billing-purpose evidence/control totals are corrected. External billing systems MAY retain this identifier as supporting evidence.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    reason_code: Annotated[
        ReasonCode,
        Field(description='Stable machine-readable reason for the post-official correction.'),
    ]
    reason_detail: Annotated[
        str | None,
        Field(
            description='Human-readable explanation. Treat as untrusted data, never agent or LLM instructions.',
            max_length=1024,
            min_length=1,
        ),
    ] = None
    accounting_period: Annotated[
        AccountingPeriod,
        Field(
            description='Period derived from the pinned billing calendar and correction policy. It is evidence metadata only: it does not authorize reopening books or altering invoices.'
        ),
    ]
    control_total_deltas: Annotated[
        list[reporting_control_total.ReportingControlTotal],
        Field(
            description="Signed deltas to apply to the named official control totals. Names and units use the adjusted revision's pinned report definition. Names MUST be unique.",
            min_length=1,
        ),
    ]
    canonical_adjustment_sha256: Annotated[
        str | None,
        Field(
            description='SHA-256 of the RFC 8785 JCS serialization of this adjustment with canonical_adjustment_sha256 omitted. Reconciled Billing consumers recompute this digest before accepting or rejecting the adjustment.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ] = None
    correction_observed_at: AwareDatetime
    created_at: AwareDatetime

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 accounting_period : AccountingPeriod
var adjusts_reporting_revision_id : str
var canonical_adjustment_sha256 : str | None
var control_total_deltas : list[ReportingControlTotal1 | ReportingControlTotal2]
var correction_observed_at : pydantic.types.AwareDatetime
var created_at : pydantic.types.AwareDatetime
var model_config
var reason_code : ReasonCode
var reason_detail : str | None
var reporting_adjustment_id : str

Inherited members

class ReportingAdjustmentReceipt (**data: Any)
Expand source code
class ReportingAdjustmentReceipt(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    reporting_receipt_id: Annotated[
        str, Field(max_length=255, min_length=16, pattern='^[A-Za-z0-9_.:-]{16,255}$')
    ]
    reporting_adjustment_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    adjusts_reporting_revision_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    supersedes_reporting_receipt_id: Annotated[
        str | None,
        Field(
            description='Optional immutable rejected receipt replaced by this new receipt for the same adjustment. Accepted current receipts are terminal.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ] = None
    status: Status
    observed_adjustment_sha256: Annotated[
        str,
        Field(
            description='Digest recomputed from the adjustment using its canonical evidence rule.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ]
    rejection_codes: Annotated[
        list[ReportingAdjustmentRejectionCode] | None, Field(min_length=1)
    ] = None
    observed_at: AwareDatetime
    received_at: AwareDatetime | 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 adjusts_reporting_revision_id : str
var model_config
var observed_adjustment_sha256 : str
var observed_at : pydantic.types.AwareDatetime
var received_at : pydantic.types.AwareDatetime | None
var rejection_codes : list[ReportingAdjustmentRejectionCode] | None
var reporting_adjustment_id : str
var reporting_receipt_id : str
var status : Status
var supersedes_reporting_receipt_id : str | None

Inherited members

class ReportingAdjustmentRejectionCode (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingAdjustmentRejectionCode(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 128, 'min_length': 1, 'pattern': '^[A-Z][A-Z0-9_]*$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingBucket (**data: Any)
Expand source code
class ReportingBucket(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    protocol: Annotated[
        cloud_storage_protocol.CloudStorageProtocol, Field(description='Cloud storage protocol')
    ]
    bucket: Annotated[
        str,
        Field(
            description='Bucket or container name',
            max_length=63,
            min_length=3,
            pattern='^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$',
        ),
    ]
    prefix: Annotated[
        str | None,
        Field(
            description='Path prefix within the bucket. Seller appends date-based partitioning beneath this prefix.',
            examples=['accounts/pinnacle/adcp', 'reporting/2024'],
            max_length=512,
            pattern='^[a-zA-Z0-9/_.-]+$',
        ),
    ] = None
    region: Annotated[
        str | None,
        Field(
            description='Cloud region for the bucket',
            examples=['us-east-1', 'europe-west1'],
            max_length=64,
            pattern='^[a-z0-9-]+$',
        ),
    ] = None
    format: Annotated[
        Format | None,
        Field(
            description='File format for delivered files. Parquet, Avro, and ORC use internal compression (the top-level compression field is ignored for these formats).'
        ),
    ] = Format.jsonl
    compression: Annotated[
        Compression | None, Field(description='Compression applied to delivered files')
    ] = Compression.gzip
    file_retention_days: Annotated[
        SchemaInt,
        Field(
            description='How long reporting files are retained in the bucket before deletion. Buyers must read files within this window. Minimum recommended: 14 days.',
            examples=[14, 30, 90],
            ge=1,
        ),
    ]
    setup_instructions: Annotated[
        AnyUrl | None,
        Field(
            description='URL to documentation for configuring buyer read access to this bucket (IAM role, service account, etc.). Operator-facing documentation — buyer agents MUST NOT auto-fetch this URL; surface it to a human operator. If an implementation fetches it (for preview), apply webhook URL SSRF validation and do not pass the fetched content into an LLM context without indirect-prompt-injection guarding. See docs/media-buy/media-buys/optimization-reporting#security-considerations-for-offline-delivery.'
        ),
    ] = 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 bucket : str
var compression : Compression | None
var file_retention_days : int
var format : Format | None
var model_config
var prefix : str | None
var protocol : CloudStorageProtocol
var region : str | None
var setup_instructions : pydantic.networks.AnyUrl | None

Inherited members

class ReportingCanonicalContentDigest (**data: Any)
Expand source code
class ReportingCanonicalContentDigest(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    algorithm: Literal['sha256'] = 'sha256'
    value: Annotated[str, Field(pattern='^[A-Fa-f0-9]{64}$')]
    canonicalization_id: Annotated[str, Field(max_length=128, min_length=1)]
    canonicalization_uri: Annotated[
        AnyUrl,
        Field(
            description='Location of the exact immutable canonicalization contract. Consumers verify canonicalization_sha256 before applying it.'
        ),
    ]
    canonicalization_sha256: Annotated[str, Field(pattern='^[A-Fa-f0-9]{64}$')]

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 algorithm : Literal['sha256']
var canonicalization_id : str
var canonicalization_sha256 : str
var canonicalization_uri : pydantic.networks.AnyUrl
var model_config
var value : str

Inherited members

class ReportingCanonicalizationContract (**data: Any)
Expand source code
class ReportingCanonicalizationContract(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    contract_version: Literal['1.0'] = '1.0'
    media_type: Literal['application/vnd.adcp.reporting-canonicalization+json'] = 'application/vnd.adcp.reporting-canonicalization+json'
    algorithm: Literal['adcp_jcs_rows_v1'] = 'adcp_jcs_rows_v1'
    schema_sha256: Annotated[
        str,
        Field(
            description='Digest of the exact row schema to which this contract applies.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ]
    primary_keys: Annotated[
        list[ReportingPrimaryKey],
        Field(
            description="Ordered scalar fields used to sort rows and reject duplicate logical rows. This MUST equal the offering's primary_keys.",
            min_length=1,
        ),
    ]
    golden_vectors: Annotated[
        GoldenVectors,
        Field(
            description='Named cross-language conformance cases: exactly one empty_report vector, exactly one ordering_encoding vector, and an optional list of additional vectors.'
        ),
    ]

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 algorithm : Literal['adcp_jcs_rows_v1']
var contract_version : Literal['1.0']
var golden_vectors : GoldenVectors
var media_type : Literal['application/vnd.adcp.reporting-canonicalization+json']
var model_config
var primary_keys : list[ReportingPrimaryKey]
var schema_sha256 : str

Inherited members

class ReportingCapabilities (**data: Any)
Expand source code
class ReportingCapabilities(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    available_reporting_frequencies: Annotated[
        list[reporting_frequency.ReportingFrequency],
        Field(description='Supported reporting frequency options', min_length=1),
    ]
    expected_delay_minutes: Annotated[
        SchemaInt,
        Field(
            description='Expected delay in minutes before reporting data becomes available (e.g., 240 for 4-hour delay)',
            examples=[240, 300, 1440],
            ge=0,
        ),
    ]
    timezone: Annotated[
        str,
        Field(
            description="Timezone for this product's reporting periods. Use 'UTC' or an IANA timezone (e.g., 'America/New_York'). This explicit reporting clock may equal Account.timezone or differ when the upstream platform reports on a separate boundary, so buyers MUST NOT infer it from Account.timezone. It is the reporting timezone for this product's delivery reporting: get_media_buy_delivery start_date, end_date, and daily_breakdown dates are calendar dates in it, and reporting_period boundaries and daily, weekly, or monthly windows fall on its calendar boundaries. Buyers MUST use this value for daily/monthly report alignment.",
            examples=['UTC', 'America/New_York', 'Europe/London', 'America/Los_Angeles'],
        ),
    ]
    supports_webhooks: Annotated[
        StrictBool,
        Field(description='Whether this product supports webhook-based reporting notifications'),
    ]
    reporting_delivery_offering_ids: Annotated[
        list[reporting_delivery_offering_id.ReportingDeliveryOfferingId] | None,
        Field(
            description='Product-scoped subset of get_adcp_capabilities.media_buy.reporting_delivery.offerings[].offering_id that packages using this product can satisfy. This binds seller-wide managed-delivery offerings to product/package eligibility. An empty array explicitly declares no managed offering; absence means product-level applicability is unknown and MUST NOT be inferred from the seller-wide list. Account, seat, credential, or provider constraints may narrow support further during sync_accounts validation.'
        ),
    ] = None
    available_metrics: Annotated[
        list[available_metric.AvailableMetric],
        Field(
            description="Metrics available in reporting. Impressions and spend are always implicitly included. When a creative format declares reported_metrics, buyers receive the intersection of these product-level metrics and the format's reported_metrics.",
            examples=[
                ['impressions', 'spend', 'clicks', 'completed_views'],
                ['impressions', 'spend', 'conversions'],
            ],
        ),
    ]
    vendor_metrics: Annotated[
        list[VendorMetric] | None,
        Field(
            description="Vendor-defined metrics this product can report, beyond the closed `available_metrics` enum. Each entry is a pointer (`{ vendor, metric_id }`) into the vendor's metric catalog — the canonical definition (standard alignment, accreditations, methodology, unit, human-readable description) lives at the vendor's `get_adcp_capabilities.measurement.metrics[]`, queried once per vendor when needed. Use this for proprietary metrics like attention scores, emissions, panel-based demographics, or platform-native social metrics not yet in the standard enum. Sellers populate values in delivery via `delivery-metrics.json#/properties/vendor_metric_values`. The metric is identified by the tuple `(vendor, metric_id)`; identifiers are namespaced by the vendor, so the same `metric_id` may mean different things in different vendors' vocabularies. Semantic uniqueness key is `(vendor.domain, vendor.brand_id, metric_id)`; sellers MUST de-duplicate before emission and MUST NOT declare the same vendor metric twice. Buyers MAY treat duplicate `(vendor, metric_id)` rows as a seller-side conformance bug. (JSON Schema `uniqueItems` is not used here because BrandRef carries optional fields whose absence/presence would defeat deep-equal — uniqueness is on the semantic key, enforced at build/validation time on the seller side.) Promotion path: when the industry converges on a metric via a published standard, the spec adds it to the closed `available_metrics` enum and the vendor extensions become historical aliases. The `vendor` MAY resolve to the selling party's own `brand.json` — a seller MAY be its own measurement vendor (DOOH sensor networks, retail-media closed loops, walled gardens) provided it publishes the metric in an `agents[type='measurement']` catalog like any other vendor and declares the relationship via `vendor_relationship`; the catalog contract is not relaxed for first-party measurement."
        ),
    ] = None
    supports_creative_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports creative-level metric breakdowns in delivery reporting (by_creative within by_package)'
        ),
    ] = None
    supports_format_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports canonical creative-format breakdowns in GET delivery reporting (by_format within by_package, keyed by format_kind). This is independent from supports_creative_breakdown because a seller may expose aggregate format-grain reporting without exposing individual creative performance.'
        ),
    ] = None
    supports_keyword_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports keyword-level metric breakdowns in delivery reporting (by_keyword within by_package)'
        ),
    ] = None
    supports_geo_breakdown: Annotated[
        geo_breakdown_support.GeographicBreakdownSupport | None,
        Field(
            description='Geographic breakdown support for this product. Declares which geo levels and systems are available for by_geo reporting within by_package.'
        ),
    ] = None
    supports_device_type_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports device type breakdowns in delivery reporting (by_device_type within by_package)'
        ),
    ] = None
    supports_device_platform_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports device platform breakdowns in delivery reporting (by_device_platform within by_package)'
        ),
    ] = None
    supports_audience_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports audience segment breakdowns in delivery reporting (by_audience within by_package)'
        ),
    ] = None
    supports_demographic_breakdown: Annotated[
        demographic_reporting_capability.DemographicReportingCapability | None,
        Field(
            description='Product-scoped demographic breakdown support for by_demographic reporting. Declares reportable age ranges and measurement systems independently from demographic targeting execution.'
        ),
    ] = None
    supports_placement_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports placement breakdowns in delivery reporting (by_placement within by_package)'
        ),
    ] = None
    supports_property_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports property breakdowns in delivery reporting (by_property within by_package).'
        ),
    ] = None
    supports_collection_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports collection breakdowns in delivery reporting (by_collection within by_package).'
        ),
    ] = None
    supports_installment_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports installment breakdowns in delivery reporting (by_installment within by_package).'
        ),
    ] = None
    supports_collection_property_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports collection × property intersection reporting (by_collection_property within by_package).'
        ),
    ] = None
    supports_installment_property_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports installment × property intersection reporting (by_installment_property within by_package).'
        ),
    ] = None
    supports_placement_property_breakdown: Annotated[
        StrictBool | None,
        Field(
            description='Whether this product supports placement × property intersection reporting (by_placement_property within by_package).'
        ),
    ] = None
    supports_spot_breakdown: Annotated[
        spot_reporting_capability.SpotReportingCapability | None,
        Field(
            description='Spot-level as-run airing-log support and metrics available at spot grain for broadcast TV, radio, and other scheduled inventory.'
        ),
    ] = None
    date_range_support: Annotated[
        DateRangeSupport,
        Field(
            description="Whether delivery data can be filtered to arbitrary date ranges. 'date_range' means the platform supports start_date/end_date parameters. 'lifetime_only' means the platform returns campaign lifetime totals and date range parameters are not accepted."
        ),
    ]
    windowed_pull_granularities: Annotated[
        list[reporting_frequency.ReportingFrequency] | None,
        Field(
            description='Granularities at which this product honors per-window pulls on get_media_buy_delivery (via request `time_granularity` + `include_window_breakdown: true`). Closes the GET-side half of the snapshot/log two-paths-parity contract for data-bearing events: a buyer who missed a webhook fire at any granularity listed here can reconstruct an identical payload by polling. Capability-scoped MUST — sellers MUST honor pulls at any granularity declared here, and MUST return UNSUPPORTED_GRANULARITY for pulls outside the set. Sellers MAY emit higher-frequency webhooks than they expose for pull (common where the webhook is a Kafka tap and historical reads go through a warehouse with coarser granularity); buyers see the gap up front via this capability and treat the webhook as primary for those frequencies. Absent or empty means the product only supports cumulative date-range pulls and full per-window recovery via GET is unavailable — see snapshot-and-log Rule 4.',
            examples=[['daily'], ['hourly', 'daily'], ['hourly', 'daily', 'monthly']],
        ),
    ] = None
    measurement_windows: Annotated[
        list[measurement_window.MeasurementWindow] | None,
        Field(
            description='Measurement maturation stages available for this product. Used by any channel where billing-grade data is produced in phases rather than arriving final on day one. Examples: broadcast/linear TV (Live → C3 → C7 DVR accumulation), DOOH (tentative plays → post-IVT/fraud-check final), digital with IVT filtering (raw → GIVT filtered → SIVT filtered), podcast (7-day downloads → 30-day downloads). Each window defines an accumulation period and expected data availability. When present, delivery reports reference a specific window_id. Sellers whose data is final on first delivery typically omit this.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var available_metrics : list[AvailableMetric]
var available_reporting_frequencies : list[ReportingFrequency]
var date_range_support : DateRangeSupport
var expected_delay_minutes : int
var measurement_windows : list[MeasurementWindow] | None
var model_config
var reporting_delivery_offering_ids : list[ReportingDeliveryOfferingId] | None
var supports_audience_breakdown : bool | None
var supports_collection_breakdown : bool | None
var supports_collection_property_breakdown : bool | None
var supports_creative_breakdown : bool | None
var supports_demographic_breakdown : DemographicReportingCapability | None
var supports_device_platform_breakdown : bool | None
var supports_device_type_breakdown : bool | None
var supports_format_breakdown : bool | None
var supports_geo_breakdown : GeographicBreakdownSupport | None
var supports_installment_breakdown : bool | None
var supports_installment_property_breakdown : bool | None
var supports_keyword_breakdown : bool | None
var supports_placement_breakdown : bool | None
var supports_placement_property_breakdown : bool | None
var supports_property_breakdown : bool | None
var supports_spot_breakdown : SpotReportingCapability | None
var supports_webhooks : bool
var timezone : str
var vendor_metrics : list[VendorMetric] | None
var windowed_pull_granularities : list[ReportingFrequency] | None

Inherited members

class ReportingCloud (*args, **kwds)
Expand source code
class ReportingCloud(StrEnum):
    aws = 'aws'
    azure = 'azure'
    gcp = 'gcp'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var aws
var azure
var gcp
class ReportingConsumerStatus (**data: Any)
Expand source code
class ReportingConsumerStatus(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    reporting_status_id: Annotated[
        str,
        Field(
            description='Consumer-issued immutable identity for this status statement. Exact retries reuse the ID and content; changed status uses a new ID and supersedes_reporting_status_id.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    supersedes_reporting_status_id: Annotated[
        str | None,
        Field(
            description="The authenticated consumer's current status leaf replaced by this statement. It must identify the same account, configuration generation, report definition, and period.",
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ] = None
    delivery_config_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    delivery_config_version: Annotated[SchemaInt, Field(ge=1)]
    report_definition_id: Annotated[
        str,
        Field(
            description='Exact immutable report definition accepted with the configuration generation, preventing unlike reporting promises from sharing a status chain.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    period: Annotated[
        Period,
        Field(
            description='Expected half-open reporting period derived from the accepted configuration generation. This identity works even when the seller omitted the corresponding obligation.'
        ),
    ]
    reporting_obligation_id: Annotated[
        str | None,
        Field(
            description='Seller-issued obligation identity when one was visible. Omitted when the consumer is reporting a missing obligation.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    reporting_revision_id: Annotated[
        str | None,
        Field(
            description='Exact revision successfully consumed or found unreadable. Omitted when no required revision was available.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    observed_revision_content_sha256: Annotated[
        str | None,
        Field(
            description='revision_content_sha256 independently recomputed from the exact consumed Core revision binding. Required for received and content_mismatch, where it proves which exact revision content the consumer read; unlike a Reconciled Billing receipt it carries no materialization evidence, row totals, canonical digest, or billing acceptance.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ] = None
    consumer_status: Annotated[
        ConsumerStatus,
        Field(
            description='received means the exact revision content was successfully consumed; obligation_missing means the independently expected period was absent from the seller ledger; revision_missing means the obligation existed but no required revision was available after expected_at; unreadable means a named revision was advertised but its exact content could not be consumed; content_mismatch means the exact revision content was read but contradicts a fact the accepted configuration generation already fixed, named by the closed mismatch_code. None of these values reconciles billing evidence, and content_mismatch in particular is not a measurement dispute.'
        ),
    ]
    status_as_of: Annotated[
        AwareDatetime,
        Field(
            description='When the consumer established this status. For received, this is when the named revision first became consumable to this consumer; sellers use it as buyer-attributed arrival evidence rather than silently substituting publication time.'
        ),
    ]
    mismatch_code: Annotated[
        MismatchCode | None,
        Field(
            description="Closed reason the consumed revision contradicts the accepted configuration generation. Each value is decidable from the obligation, the pinned report definition, and the revision itself, with no reference to either party's own measurement. scope_media_buy_missing: a media buy frozen in the obligation's media_buy_ids denominator is absent from the revision and is not represented by an explicit zero row, so the revision cannot distinguish zero delivery from an omitted buy. coverage_short: the revision covers fewer packages than the obligation's frozen coverage.covered_package_ids claims. metric_missing: a metric named in the pinned report definition's metrics[].name is absent from the revision. schema_nonconformant: rows do not validate against the reporting profile's pinned schema_uri and schema_sha256. currency_mismatch: a value's unit disagrees with the unit the pinned report definition fixed for that metric, or a control total's unit disagrees with the profile-defined unit for that name. period_mismatch: the revision carries a time dimension declared by the pinned grain whose values fall outside the obligation's half-open period. Precedence when more than one applies: schema_nonconformant is used only when the failure is structural validation against the pinned schema; a metric that is simply absent uses metric_missing even when the pinned schema declares it required. Each names a contract fact already fixed by the accepted generation, never a difference of opinion about counts. Agents dispatch on this value, not on prose."
        ),
    ] = None
    failure_code: Annotated[
        FailureCode | None,
        Field(
            description='Typed reason a named revision was unreadable. Agents dispatch on this value, not prose or provider response bodies.'
        ),
    ] = None
    consumer_commit_ref: Annotated[
        str | None,
        Field(
            description='Optional opaque, non-secret consumer checkpoint, transaction, or load reference. It is operational evidence, not authorization, a credential, a URL, or instructions; receivers compare or display it as inert text and never dereference or execute it.',
            max_length=512,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,512}$',
        ),
    ] = None
    seller_ledger_snapshot_id: Annotated[
        str | None,
        Field(
            description='Optional seller-issued get_reporting_status snapshot on which this statement was based. It is evidence context, not consumer authority over that snapshot.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    seller_ledger_as_of: Annotated[
        AwareDatetime | None,
        Field(
            description='ledger_as_of echoed from seller_ledger_snapshot_id. Present if and only if seller_ledger_snapshot_id is present.'
        ),
    ] = None
    recorded_at: Annotated[
        AwareDatetime | None,
        Field(description='When the seller durably recorded this immutable statement.'),
    ] = 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 consumer_commit_ref : str | None
var consumer_status : ConsumerStatus
var delivery_config_id : str
var delivery_config_version : int
var failure_code : FailureCode | None
var mismatch_code : MismatchCode | None
var model_config
var observed_revision_content_sha256 : str | None
var period : Period
var recorded_at : pydantic.types.AwareDatetime | None
var report_definition_id : str
var reporting_obligation_id : str | None
var reporting_revision_id : str | None
var reporting_status_id : str
var seller_ledger_as_of : pydantic.types.AwareDatetime | None
var seller_ledger_snapshot_id : str | None
var status_as_of : pydantic.types.AwareDatetime
var supersedes_reporting_status_id : str | None

Inherited members

class ReportingControlTotal1 (**data: Any)
Expand source code
class ReportingControlTotal1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: Annotated[
        str, Field(max_length=128, min_length=1, pattern='^[A-Za-z][A-Za-z0-9_.:-]{0,127}$')
    ]
    value: Annotated[
        str,
        Field(
            description='Canonical base-10 integer with no exponent, grouping separator, decimal point, or insignificant leading zeroes.',
            pattern='^-?(?:0|[1-9][0-9]*)$',
        ),
    ]
    value_type: Literal['integer'] = 'integer'
    unit: Annotated[
        str | None,
        Field(
            description='Profile-defined unit such as impressions or an ISO 4217 currency code.',
            max_length=32,
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var name : str
var unit : str | None
var value : str
var value_type : Literal['integer']

Inherited members

class ReportingControlTotal2 (**data: Any)
Expand source code
class ReportingControlTotal2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: Annotated[
        str, Field(max_length=128, min_length=1, pattern='^[A-Za-z][A-Za-z0-9_.:-]{0,127}$')
    ]
    value: Annotated[
        str,
        Field(
            description='Canonical base-10 decimal with no exponent, grouping separator, or insignificant leading zeroes.',
            pattern='^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$',
        ),
    ]
    value_type: Literal['decimal'] = 'decimal'
    unit: Annotated[
        str | None,
        Field(
            description='Profile-defined unit such as impressions or an ISO 4217 currency code.',
            max_length=32,
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var name : str
var unit : str | None
var value : str
var value_type : Literal['decimal']

Inherited members

class ReportingCoverage (**data: Any)
Expand source code
class ReportingCoverage(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    status: Status
    evaluated_at: AwareDatetime
    media_buy_ids: Annotated[
        list[ReportingMediaBuyId],
        Field(
            description='Exact media-buy denominator, including unsupported and unknown buys. An empty array is an explicitly evaluated zero-buy scope.'
        ),
    ]
    fully_covered_media_buy_ids: list[ReportingMediaBuyId]
    partially_covered_media_buy_ids: list[ReportingMediaBuyId]
    unsupported_media_buy_ids: list[ReportingMediaBuyId]
    unknown_media_buy_ids: list[ReportingMediaBuyId]
    package_ids: Annotated[
        list[ReportingPackageId],
        Field(description='Exact package denominator for the evaluated media buys.'),
    ]
    covered_package_ids: list[ReportingPackageId]
    unsupported_package_ids: list[ReportingPackageId]
    unknown_package_ids: list[ReportingPackageId]
    limitations: Annotated[
        list[Limitation],
        Field(
            description='Stable reasons that some requested scope is not covered by the exact selected offering. These are capability facts, not delivery failures.'
        ),
    ]

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 covered_package_ids : list[ReportingPackageId]
var evaluated_at : pydantic.types.AwareDatetime
var fully_covered_media_buy_ids : list[ReportingMediaBuyId]
var limitations : list[Limitation]
var media_buy_ids : list[ReportingMediaBuyId]
var model_config
var package_ids : list[ReportingPackageId]
var partially_covered_media_buy_ids : list[ReportingMediaBuyId]
var status : Status
var unknown_media_buy_ids : list[ReportingMediaBuyId]
var unknown_package_ids : list[ReportingPackageId]
var unsupported_media_buy_ids : list[ReportingMediaBuyId]
var unsupported_package_ids : list[ReportingPackageId]

Inherited members

class ReportingDatasetShareDestination1 (**data: Any)
Expand source code
class ReportingDatasetShareDestination1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['existing'] = 'existing'
    destination_ref: Annotated[
        str,
        Field(
            description='Seller-issued immutable recipient/destination-generation reference returned by sync_agent_configuration, an earlier sync, or bilateral setup.',
            max_length=255,
            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 destination_ref : str
var mode : Literal['existing']
var model_config

Inherited members

class ReportingDatasetShareDestination2 (**data: Any)
Expand source code
class ReportingDatasetShareDestination2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['provision'] = 'provision'
    provider: Annotated[
        Provider,
        Field(description='Data-sharing platform, such as databricks.com or snowflake.com.'),
    ]
    access_mode: Annotated[
        str,
        Field(
            description='Provider access family, such as databricks_to_databricks, open_sharing, or secure_data_sharing.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    recipient: Annotated[
        Recipient,
        Field(
            description='Intended buyer principal. The identity is interpreted by the provider and access mode; for example, a Databricks sharing identifier, Snowflake organization/account pair, or Open Sharing recipient email. It is an identifier, never a credential.'
        ),
    ]

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 access_mode : str
var mode : Literal['provision']
var model_config
var provider : Provider
var recipient : Recipient

Inherited members

class ReportingDeliveryCapabilities (**data: Any)
Expand source code
class ReportingDeliveryCapabilities(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    supported: Literal[True]
    reliable_reporting_version: Annotated[
        Literal['1.0'] | None,
        Field(
            description='Explicit adoption declaration for the proper-name AdCP 3.2 Reliable Reporting contract. Presence, together with supported: true and the media_buy.reporting_delivery experimental feature gate, is the affirmative machine-readable answer. Absence denotes the earlier experimental managed-reporting shape.'
        ),
    ] = None
    managed_delivery: Annotated[
        StrictBool | None,
        Field(
            description='Tier flag: this seller supports managed file, dataset-share, or warehouse delivery. Offerings whose method names a delivery pattern require this tier. When false or absent, every offering is API-delivered and Core-only.'
        ),
    ] = None
    reconciled_billing: Annotated[
        StrictBool | None,
        Field(
            description='Tier flag: this seller supports canonical-digest verification and authenticated consumer receipts for both report materializations and post-official adjustments through receipt_task. Offerings with reconciliation_mode consumer_receipt and billing-grade canonicalization require this tier.'
        ),
    ] = None
    configuration_task: Literal['sync_accounts'] | None = None
    status_task: Literal['get_reporting_status'] | None = None
    consumer_status_task: Annotated[
        Literal['sync_reporting_status'] | None,
        Field(
            description='Opt-in consumer-status loop during the published migration window, becoming required Core in the next eligible minor after that window. Buyers call this seller-hosted task to record whether each expected reporting period was received, missing, or unreadable. Buyers expose no reverse endpoint, and the status is not a billing receipt.'
        ),
    ] = None
    revision_content_task: Annotated[
        Literal['get_media_buy_delivery'] | None,
        Field(
            description='Reliable Reporting exact-content read: callers select reporting_revision_id and receive immutable revision metadata plus authoritative canonical reporting_rows.'
        ),
    ] = None
    receipt_task: Annotated[
        Literal['sync_reporting_receipts'] | None,
        Field(
            description='Required when reconciled_billing is true: the task consumers call to submit and read back authenticated revision and adjustment receipts.'
        ),
    ] = None
    readiness_notification: Annotated[
        Literal['reporting.delivery_ready'] | None,
        Field(
            description='Optional managed-delivery-only positive-readiness doorbell. It names a materialization at a destination, so Core sellers MUST omit it.'
        ),
    ] = None
    status_notification: Annotated[
        Literal['reporting.status_changed'] | None,
        Field(
            description='Optional tier-independent invalidation doorbell for health transitions in either direction, including clock-driven waiting-to-delayed and delayed-to-action_required. Valid for Core: it names no destination. Polling status_task remains the authoritative recovery path whether or not this is offered.'
        ),
    ] = None
    ledger_notification: Annotated[
        Literal['reporting.ledger_changed'] | None,
        Field(
            description='Optional tier-independent invalidation for every newly committed revision or post-official adjustment, even when health does not change. Receivers repair through get_reporting_status changes_after; polling remains authoritative.'
        ),
    ] = None
    offerings: Annotated[
        list[reporting_delivery_offering.ReportingDeliveryOffering],
        Field(
            description='Atomic supported feed/profile/schedule/finality/method combinations. offering_id values MUST be unique.',
            min_length=1,
        ),
    ]
    automated_recovery_window_seconds: Annotated[
        SchemaInt,
        Field(
            description='Maximum late interval during which a due obligation may remain delayed while automated recovery continues before action_required.',
            ge=0,
        ),
    ]
    status_retention_days: Annotated[
        SchemaInt,
        Field(
            description='Minimum period for which obligation, revision, and materialization metadata remain queryable.',
            ge=1,
        ),
    ]
    consumer_mismatch_escalation_seconds: Annotated[
        SchemaInt | None,
        Field(
            description="Maximum interval after a CONSUMER_STATUS_MISMATCH issue's opened_at during which the seller may keep that issue at a non-escalated recommended_action. After it, the issue MUST be action_required with a contact_ recommended_action naming the diagnosed responsible_party. Declaring it requires operations_contact so the escalation has a destination. Absence means the seller publishes no escalation commitment; it never means an unbounded one.",
            ge=0,
        ),
    ] = None
    operations_contact: Annotated[
        OperationsContact | None,
        Field(
            description='Optional non-secret human escalation path for reporting issues the protocol cannot resolve. It is display metadata for an operator, not an AdCP endpoint: agents MUST NOT dereference, probe, or send protocol traffic to these values, and they carry no authorization. Required when consumer_mismatch_escalation_seconds is advertised.'
        ),
    ] = None
    reliability_statistics: Annotated[
        list[reporting_reliability_statistics.ReportingReliabilityStatistics] | None,
        Field(
            description='Optional evidence-scoped observed performance for advertised offerings. offering_id values MUST be unique and name offerings in this capability block.'
        ),
    ] = None
    resource_retention_days: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum period after publication for which at least one verified exact materialization remains readable to every still-authorized intended consumer.',
            ge=1,
        ),
    ] = None
    supports_webhook_activity: StrictBool | None = None
    authorization_revocation_seconds: Annotated[
        SchemaInt | None,
        Field(
            description="Maximum delay after caller/account authorization ends before seller-controlled transport access, provider grants, and write credentials are revoked. It cannot revoke a buyer's access to data already written into a buyer-owned destination.",
            ge=0,
        ),
    ] = None

    @model_validator(mode='after')
    def _validate_reporting_tiers(self) -> ReportingDeliveryCapabilities:
        if self.reconciled_billing is True and self.managed_delivery is not True:
            raise ValueError('reconciled_billing requires managed_delivery')
        if self.readiness_notification is not None and self.managed_delivery is not True:
            raise ValueError('readiness_notification requires managed_delivery')
        if self.receipt_task is not None and self.reconciled_billing is not True:
            raise ValueError('receipt_task requires reconciled_billing')
        return self

    @model_serializer(mode='wrap')
    def _omit_absent_reporting_promises(
        self, handler: SerializerFunctionWrapHandler
    ) -> dict[str, Any]:
        return {key: value for key, value in handler(self).items() if value is not 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 authorization_revocation_seconds : int | None
var automated_recovery_window_seconds : int
var configuration_task : Literal['sync_accounts'] | None
var consumer_mismatch_escalation_seconds : int | None
var consumer_status_task : Literal['sync_reporting_status'] | None
var ledger_notification : Literal['reporting.ledger_changed'] | None
var managed_delivery : bool | None
var model_config
var offerings : list[ReportingDeliveryOffering]
var operations_contact : OperationsContact | None
var readiness_notification : Literal['reporting.delivery_ready'] | None
var receipt_task : Literal['sync_reporting_receipts'] | None
var reconciled_billing : bool | None
var reliability_statistics : list[ReportingReliabilityStatistics] | None
var reliable_reporting_version : Literal['1.0'] | None
var resource_retention_days : int | None
var revision_content_task : Literal['get_media_buy_delivery'] | None
var status_notification : Literal['reporting.status_changed'] | None
var status_retention_days : int
var status_task : Literal['get_reporting_status'] | None
var supported : Literal[True]
var supports_webhook_activity : bool | None

Inherited members

class ReportingDeliveryConfigLifecycleState (*args, **kwds)
Expand source code
class ReportingDeliveryConfigLifecycleState(StrEnum):
    pending_validation = 'pending_validation'
    pending_setup = 'pending_setup'
    ready = 'ready'
    action_required = 'action_required'
    inactive = 'inactive'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var action_required
var inactive
var pending_setup
var pending_validation
var ready
class ReportingDeliveryConfiguration (**data: Any)
Expand source code
class ReportingDeliveryConfiguration(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    delivery_config_id: Annotated[
        str,
        Field(
            description='Caller-selected stable identifier, unique within the authenticated caller and account.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    delivery_config_version: Annotated[
        SchemaInt,
        Field(
            description='Caller-selected immutable semantic generation. Increment when feed/profile/scope/finality/schedule/method/destination changes; lifecycle fields may change in place.',
            ge=1,
        ),
    ]
    offering_id: Annotated[
        str,
        Field(
            description='Atomic reporting offering advertised by the seller that binds feed, profile, schedule, finality, and delivery support.',
            max_length=128,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,128}$',
        ),
    ]
    active: Annotated[
        StrictBool,
        Field(
            description='Whether new reporting obligations should use this configuration. Inactive configurations remain visible for historical resolution.'
        ),
    ]
    feed_purpose: reporting_delivery_offering.ReportingFeedPurpose
    report_definition_id: Annotated[
        str,
        Field(
            description='Exact immutable semantic definition selected from the offering. This makes the expected obligation identity independently derivable and prevents attribution, timezone, source-mapping, or restatement-policy drift behind a profile label.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    reporting_profile: Annotated[
        str,
        Field(
            description='Versioned semantic profile for the aggregate report, such as media_buy_delivery_v1. It MUST match the selected offering.',
            max_length=128,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,128}$',
        ),
    ]
    scope: Annotated[Scope, Field(description='Media buys covered by this configuration.')]
    coverage_requirement: Annotated[
        CoverageRequirement,
        Field(
            description='Whether every package in the resolved media-buy scope must support the exact selected offering. full fails closed when any package is unsupported or unknown. allow_partial permits publication only for the explicitly covered package denominator; every revision and status response still exposes partial coverage and MUST NOT present covered-subset totals as whole-buy totals.'
        ),
    ]
    required_finality: Annotated[
        reporting_finality.ReportingFinality,
        Field(
            description='Finality the durable path must ultimately provide. Snapshot delivery may still precede an official requirement.'
        ),
    ]
    reconciliation_mode: Annotated[
        reporting_reconciliation_mode.ReportingReconciliationMode,
        Field(
            description='Whether producer-side delivery evidence is sufficient or the selected consumer must submit an authenticated matching receipt. A seller-authoritative billing feed MUST use consumer_receipt.'
        ),
    ]
    authoritative_party: Annotated[
        AuthoritativeParty | None,
        Field(
            description="Reserved: which party's count of this feed is authoritative. seller (the default, and the only value any 3.2 seller accepts) means the seller produces every revision and the consumer may only attest to what it consumed. consumer is reserved for the buyer-deposited billing revision task scoped to a later minor; until that task exists sellers MUST reject it with UNSUPPORTED_FEATURE. Reserving the field now keeps a future buyer-basis billing feed additive instead of breaking the billing-feed constraints. See https://github.com/adcontextprotocol/adcp/issues/7440."
        ),
    ] = AuthoritativeParty.seller
    schedule: reporting_schedule.ReportingSchedule
    method: reporting_delivery_method.ReportingDeliveryMethod | None = None
    revocation_effective_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Optional requested cutoff for deactivation. No new publication may begin after the applied cutoff; historical access is limited to the contracted recovery window.'
        ),
    ] = 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 active : bool
var authoritative_party : AuthoritativeParty | None
var coverage_requirement : CoverageRequirement
var delivery_config_id : str
var delivery_config_version : int
var feed_purpose : ReportingFeedPurpose
var method : ReportingDeliveryMethod1 | ReportingDeliveryMethod2 | ReportingDeliveryMethod3 | None
var model_config
var offering_id : str
var reconciliation_mode : ReportingReconciliationMode
var report_definition_id : str
var reporting_profile : str
var required_finality : ReportingFinality
var revocation_effective_at : pydantic.types.AwareDatetime | None
var schedule : ReportingSchedule
var scope : Scope

Inherited members

class ReportingDeliveryConfigurationState (**data: Any)
Expand source code
class ReportingDeliveryConfigurationState(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    configuration: reporting_delivery_config.ReportingDeliveryConfiguration
    state: ReportingDeliveryConfigLifecycleState
    destination_ref: Annotated[
        str | None,
        Field(
            description='Seller-issued immutable destination-generation reference. It is caller-scoped and reusable across separately authorized account configurations; it is not itself account authority or a bearer grant. Present when and only when the configuration selects a managed-delivery offering; a Core (API-delivered) configuration becomes ready with no destination at all.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    validated_at: AwareDatetime | None = None
    activated_at: AwareDatetime | None = None
    deactivated_at: AwareDatetime | None = None
    publication_stopped_at: Annotated[
        AwareDatetime | None,
        Field(
            description='Applied schedule boundary at or after deactivation. No obligation whose period starts at or after this cutoff is created; earlier obligations remain owed through their SLA and recovery lifecycle.'
        ),
    ] = None
    seller_managed_access_ends_at: Annotated[
        AwareDatetime | None,
        Field(
            description='End of historical access to a producer-hosted share/resource for a still-authorized principal after voluntary deactivation. Inapplicable to data already written into a buyer-owned destination.'
        ),
    ] = None
    current_coverage: Annotated[
        reporting_coverage.ReportingCoverage | None,
        Field(
            description='Current effective product/package coverage for the selected offering and resolved account. This setup-time view may change as media buys or provider capabilities change; each period obligation later freezes its own authoritative coverage.'
        ),
    ] = None
    setup: Annotated[
        Setup | None,
        Field(
            description='Secret-free next step when provider-side authorization or recipient activation cannot be completed automatically.'
        ),
    ] = None
    issues: Annotated[
        list[reporting_status_issue.ReportingStatusIssue] | None, Field(min_length=1)
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var activated_at : pydantic.types.AwareDatetime | None
var configuration : ReportingDeliveryConfiguration
var current_coverage : ReportingCoverage | None
var deactivated_at : pydantic.types.AwareDatetime | None
var destination_ref : str | None
var issues : list[ReportingStatusIssue] | None
var model_config
var publication_stopped_at : pydantic.types.AwareDatetime | None
var seller_managed_access_ends_at : pydantic.types.AwareDatetime | None
var setup : Setup | None
var state : ReportingDeliveryConfigLifecycleState
var validated_at : pydantic.types.AwareDatetime | None

Inherited members

class ReportingDeliveryMethod1 (**data: Any)
Expand source code
class ReportingDeliveryMethod1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Annotated[
        Literal['file_transfer'],
        Field(
            description='Immutable file/object publication with a manifest-last commit boundary.'
        ),
    ] = 'file_transfer'
    transport: Annotated[
        str,
        Field(
            description='Storage transport such as s3, gcs, azure_blob, or sftp.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    orchestration: ReportingOrchestration
    destination: reporting_write_destination.ReportingWriteDestination
    format: Annotated[Format, Field(description='Physical file format.')]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var destination : ReportingWriteDestination1 | ReportingWriteDestination2
var format : Format
var model_config
var orchestration : ReportingOrchestration
var pattern : Literal['file_transfer']
var transport : str

Inherited members

class ReportingDeliveryMethod2 (**data: Any)
Expand source code
class ReportingDeliveryMethod2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Annotated[
        Literal['dataset_share'],
        Field(
            description="Producer-hosted relation or share read through the intended recipient's access path."
        ),
    ] = 'dataset_share'
    transport: Annotated[
        str,
        Field(
            description='Sharing transport such as delta_sharing, snowflake_secure_sharing, or bigquery_authorized_view.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    orchestration: ReportingOrchestration
    destination: reporting_dataset_share_destination.ReportingDatasetShareDestination

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 destination : ReportingDatasetShareDestination1 | ReportingDatasetShareDestination2
var model_config
var orchestration : ReportingOrchestration
var pattern : Literal['dataset_share']
var transport : str

Inherited members

class ReportingDeliveryMethod3 (**data: Any)
Expand source code
class ReportingDeliveryMethod3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    pattern: Annotated[
        Literal['warehouse_materialization'],
        Field(description='Exact-revision publication into a warehouse relation or partition.'),
    ] = 'warehouse_materialization'
    transport: Annotated[
        str,
        Field(
            description='Warehouse or transfer transport such as bigquery, snowflake, databricks_sql, or gam_bigquery_transfer.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ]
    orchestration: ReportingOrchestration
    destination: reporting_write_destination.ReportingWriteDestination

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 destination : ReportingWriteDestination1 | ReportingWriteDestination2
var model_config
var orchestration : ReportingOrchestration
var pattern : Literal['warehouse_materialization']
var transport : str

Inherited members

class ReportingDeliveryOffering (**data: Any)
Expand source code
class ReportingDeliveryOffering(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    offering_id: Annotated[
        str, Field(max_length=128, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,128}$')
    ]
    feed_purpose: ReportingFeedPurpose
    report_definition_id: Annotated[
        str,
        Field(
            description='Immutable semantic definition for metric, grain, attribution, action-report-time, timezone/calendar, source/API mapping, and restatement/finality policy. Configurations and revisions MUST echo this exact value.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    report_definition_uri: Annotated[
        AnyUrl,
        Field(
            description='Retrievable immutable reporting-report-definition.json document on the authenticated seller/provider or AdCP-registry origin.'
        ),
    ]
    report_definition_sha256: Annotated[
        str,
        Field(
            description='Digest of the exact report-definition bytes. SDKs verify this before parsing and cache by digest.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ]
    reporting_profile: Annotated[
        ReportingProfile,
        Field(
            description='Machine-readable semantic and validation contract for delivered rows. The canonicalization_* fields describe the external-materialization canonical-digest contract and are required only for offerings under the reconciled_billing tier; Core and managed-delivery offerings omit those fields but every Core revision still carries the fixed RFC 8785/JCS revision-binding digest.'
        ),
    ]
    schedule: Annotated[
        reporting_schedule_offering.ReportingScheduleOffering,
        Field(
            description='Period and availability SLA this offering can honor. For example, PT1H with snapshot finality explicitly advertises hourly provisional snapshots; a separate P1D official offering advertises daily finalized reporting.'
        ),
    ]
    supported_finality: Annotated[
        list[reporting_finality.ReportingFinality],
        Field(
            description='Finality classes available under this exact report definition, schedule, and delivery method. snapshot is an explicit provisional capability, not inferred from poll frequency. Use separate atomic offerings when snapshot and official schedules or methods differ.',
            min_length=1,
        ),
    ]
    reconciliation_mode: Annotated[
        reporting_reconciliation_mode.ReportingReconciliationMode,
        Field(
            description='Receipt contract included in this atomic offering. Billing offerings MUST require consumer_receipt.'
        ),
    ]
    method: Annotated[
        Method | None,
        Field(
            description='Managed delivery method for this offering. Omit for a Core (API-delivered) offering: rows flow through existing get_media_buy_delivery and reporting_webhook transports and no destination is involved. Present only when the seller advertises managed_delivery.'
        ),
    ] = 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 feed_purpose : ReportingFeedPurpose
var method : Method | None
var model_config
var offering_id : str
var reconciliation_mode : ReportingReconciliationMode
var report_definition_id : str
var report_definition_sha256 : str
var report_definition_uri : pydantic.networks.AnyUrl
var reporting_profile : ReportingProfile
var schedule : ReportingScheduleOffering
var supported_finality : list[ReportingFinality]

Inherited members

class ReportingDeliveryOfferingId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingDeliveryOfferingId(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 128, 'min_length': 1, 'pattern': '^[A-Za-z0-9_.:-]{1,128}$'}
    _json_schema_extra = {
        'description': 'Identifier of one seller-advertised managed reporting-delivery offering, matching get_adcp_capabilities.media_buy.reporting_delivery.offerings[].offering_id. Shared by the legacy and canonical product reporting capabilities.',
        'title': 'Reporting Delivery Offering ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingDeliveryPattern (*args, **kwds)
Expand source code
class ReportingDeliveryPattern(StrEnum):
    file_transfer = 'file_transfer'
    dataset_share = 'dataset_share'
    warehouse_materialization = 'warehouse_materialization'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var dataset_share
var file_transfer
var warehouse_materialization
class ReportingDeliveryReadyWebhook (**data: Any)
Expand source code
class ReportingDeliveryReadyWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Stable across transport retries of this fire; new for a later re-emission.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Stable for this logical materialization-ready event across re-emissions.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Literal['reporting.delivery_ready'] = 'reporting.delivery_ready'
    fired_at: AwareDatetime
    subscriber_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    account_id: Annotated[str, Field(min_length=1)]
    delivery_config_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    delivery_config_version: Annotated[SchemaInt, Field(ge=1)]
    reporting_revision_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_materialization_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    readiness: Readiness
    finality: reporting_finality.ReportingFinality
    data_through: AwareDatetime | None
    feed_purpose: reporting_delivery_offering.ReportingFeedPurpose

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 account_id : str
var data_through : pydantic.types.AwareDatetime | None
var delivery_config_id : str
var delivery_config_version : int
var feed_purpose : ReportingFeedPurpose
var finality : ReportingFinality
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var model_config
var notification_id : str
var notification_type : Literal['reporting.delivery_ready']
var readiness : Readiness
var reporting_materialization_id : str
var reporting_revision_id : str
var subscriber_id : str

Inherited members

class ReportingFeedPurpose (*args, **kwds)
Expand source code
class ReportingFeedPurpose(StrEnum):
    pacing = 'pacing'
    analytics = 'analytics'
    billing = 'billing'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var analytics
var billing
var pacing
class ReportingFileCompression (*args, **kwds)
Expand source code
class ReportingFileCompression(StrEnum):
    none = 'none'
    gzip = 'gzip'
    zstd = 'zstd'
    snappy = 'snappy'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var gzip
var none
var snappy
var zstd
class ReportingFileEntry (**data: Any)
Expand source code
class ReportingFileEntry(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    object_ref: reporting_file_object_ref.ReportingFileObjectReference
    native_version_ref: reporting_native_version_ref.ReportingNativeVersionReference | None = None
    size_bytes: Annotated[SchemaInt, Field(ge=0)]
    sha256: Annotated[str, Field(pattern='^[A-Fa-f0-9]{64}$')]
    row_count: Annotated[SchemaInt, Field(ge=0)]
    partition: Annotated[dict[str, str] | None, Field(max_length=32)] = 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 model_config
var native_version_ref : ReportingNativeVersionReference | None
var object_ref : ReportingFileObjectReference
var partition : dict[str, str] | None
var row_count : int
var sha256 : str
var size_bytes : int

Inherited members

class ReportingFileManifest (**data: Any)
Expand source code
class ReportingFileManifest(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    manifest_version: Literal['1.0'] = '1.0'
    complete: Literal[True]
    reporting_revision_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_obligation_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_materialization_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    period: Period
    format: Format
    compression: reporting_file_compression.ReportingFileCompression
    files: Annotated[list[reporting_file_entry.ReportingFileEntry], Field(min_length=1)]
    total_size_bytes: Annotated[SchemaInt, Field(ge=0)]
    row_count: Annotated[SchemaInt, Field(ge=0)]
    control_totals: list[reporting_control_total.ReportingControlTotal]
    created_at: AwareDatetime

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 complete : Literal[True]
var compression : ReportingFileCompression
var control_totals : list[ReportingControlTotal1 | ReportingControlTotal2]
var created_at : pydantic.types.AwareDatetime
var files : list[ReportingFileEntry]
var format : Format
var manifest_version : Literal['1.0']
var model_config
var period : Period
var reporting_materialization_id : str
var reporting_obligation_id : str
var reporting_revision_id : str
var row_count : int
var total_size_bytes : int

Inherited members

class ReportingFileObjectReference (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingFileObjectReference(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 1024, 'min_length': 1}
    _json_schema_extra = {
        'description': 'Credential-free, destination-relative reference to one reporting data object. For an object store, this is the decoded object key relative to the configured destination, not an absolute URI and not a URI with a version query parameter. Providers URI-encode this value only when constructing their own storage request. The 1024-character limit accommodates an S3 object key of up to 1024 UTF-8 bytes because every Unicode character occupies at least one UTF-8 byte; JSON Schema maxLength counts characters rather than bytes.',
        'title': 'Reporting File Object Reference',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingFrequency (*args, **kwds)
Expand source code
class ReportingFrequency(StrEnum):
    hourly = 'hourly'
    daily = 'daily'
    monthly = 'monthly'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var daily
var hourly
var monthly
class ReportingLedgerChangedWebhook (**data: Any)
Expand source code
class ReportingLedgerChangedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Random per distinct fire and stable across transport retries, scoped to the authenticated sender.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Stable per committed ledger record; re-emissions reuse it.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Literal['reporting.ledger_changed'] = 'reporting.ledger_changed'
    fired_at: AwareDatetime
    subscriber_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    account_id: Annotated[str, Field(min_length=1)]
    change_kind: ChangeKind
    reporting_revision_id: Annotated[
        str | None, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ] = None
    supersedes_reporting_revision_id: Annotated[
        str | None, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ] = None
    finality: reporting_finality.ReportingFinality | None = None
    reporting_adjustment_id: Annotated[
        str | None, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ] = None
    adjusts_reporting_revision_id: Annotated[
        str | None, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ] = None
    ext: ext_1.ExtensionObject | 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 account_id : str
var adjusts_reporting_revision_id : str | None
var change_kind : ChangeKind
var ext : ExtensionObject | None
var finality : ReportingFinality | None
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var model_config
var notification_id : str
var notification_type : Literal['reporting.ledger_changed']
var reporting_adjustment_id : str | None
var reporting_revision_id : str | None
var subscriber_id : str
var supersedes_reporting_revision_id : str | None

Inherited members

class ReportingMaterialization (**data: Any)
Expand source code
class ReportingMaterialization(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    reporting_materialization_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_revision_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_obligation_id: Annotated[
        str,
        Field(
            description='Destination-specific obligation this materialization attempts to satisfy.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    delivery_config_id: Annotated[
        str,
        Field(
            description='Durable configuration that requested this materialization.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    delivery_config_version: Annotated[SchemaInt, Field(ge=1)]
    destination_ref: Annotated[
        str,
        Field(
            description='Immutable caller-owned destination generation selected by the account-authorized obligation. It may be reused by the same caller across other independently authorized accounts.',
            max_length=255,
            min_length=1,
        ),
    ]
    feed_purpose: reporting_delivery_offering.ReportingFeedPurpose
    method: Method
    transport: Annotated[
        str | None, Field(max_length=64, min_length=1, pattern='^[a-z][a-z0-9_.-]*$')
    ] = None
    attempt: Annotated[SchemaInt, Field(ge=1)]
    status: Annotated[
        Status,
        Field(
            description='Lifecycle of this attempt. pending may transition once to available, delivered, or failed; terminal evidence is immutable. Staleness is evaluated in get_reporting_status health, not stored as a materialization state.'
        ),
    ]
    ready_at: Annotated[
        AwareDatetime | None,
        Field(description='When consumer-path or destination verification completed.'),
    ] = None
    failed_at: AwareDatetime | None = None
    failure_code: Annotated[
        str | None,
        Field(
            description='Stable safe failure classification. MUST NOT include credentials or provider response bodies.',
            max_length=128,
            min_length=1,
            pattern='^[A-Z][A-Z0-9_]*$',
        ),
    ] = None
    resource: reporting_resource.ReportingResource | None = None
    verification: reporting_verification.ReportingVerification | None = None
    created_at: AwareDatetime

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 attempt : int
var created_at : pydantic.types.AwareDatetime
var delivery_config_id : str
var delivery_config_version : int
var destination_ref : str
var failed_at : pydantic.types.AwareDatetime | None
var failure_code : str | None
var feed_purpose : ReportingFeedPurpose
var method : Method
var model_config
var ready_at : pydantic.types.AwareDatetime | None
var reporting_materialization_id : str
var reporting_obligation_id : str
var reporting_revision_id : str
var resource : ReportingResource | None
var status : Status
var transport : str | None
var verification : ReportingVerification | None

Inherited members

class ReportingMediaBuyId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingMediaBuyId(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}
    _json_schema_extra = {'title': 'Reporting Media Buy ID'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingMode (*args, **kwds)
Expand source code
class ReportingMode(StrEnum):
    exact_predicates = 'exact_predicates'
    enumerated_intervals = 'enumerated_intervals'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var enumerated_intervals
var exact_predicates
class ReportingNativeVersionReference (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingNativeVersionReference(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 1024, 'min_length': 1}
    _json_schema_extra = {
        'description': 'Credential-free, decoded provider-native immutable version reference, such as an S3 VersionId, GCS generation, table version, transaction, snapshot, manifest generation, job, or run. This is not URI-encoded or concatenated into an object_ref; URI-encode it only when constructing a provider request. The 1024-character limit accommodates a provider value of up to 1024 UTF-8 bytes because every Unicode character occupies at least one UTF-8 byte; JSON Schema maxLength counts characters rather than bytes.',
        'title': 'Reporting Native Version Reference',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingObligation (**data: Any)
Expand source code
class ReportingObligation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    reporting_obligation_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    delivery_config_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    delivery_config_version: Annotated[SchemaInt, Field(ge=1)]
    report_definition_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    feed_purpose: reporting_delivery_offering.ReportingFeedPurpose
    reporting_profile: Annotated[str, Field(max_length=128, min_length=1)]
    account_id: Annotated[str, Field(min_length=1)]
    media_buy_ids: Annotated[
        list[reporting_coverage.ReportingMediaBuyId],
        Field(
            description='Exact frozen media-buy denominator resolved for this period, including buys with zero rows. An empty array is the definitive zero-buy set; omission is never used to mean all, empty, or unknown.'
        ),
    ]
    scope_resolved_at: Annotated[
        AwareDatetime,
        Field(
            description='Instant at which the configured scope was resolved and frozen for this obligation. For all_media_buys, include every caller-authorized account media buy whose effective flight overlaps the half-open period and was known by this cutoff. Later-created or backdated buys do not rewrite this obligation.'
        ),
    ]
    coverage: Annotated[
        reporting_coverage.ReportingCoverage,
        Field(
            description='Immutable effective coverage of the exact selected offering at this period boundary. Delivery health is evaluated separately over the covered denominator.'
        ),
    ]
    period: Period
    expected_at: AwareDatetime
    schedule: Annotated[
        reporting_schedule.ReportingSchedule,
        Field(description='Resolved immutable schedule generation that created this obligation.'),
    ]
    destination_ref: Annotated[
        str | None,
        Field(
            description='Immutable caller-owned destination generation selected by this account-authorized obligation. The account/configuration join—not possession of this reusable reference—authorizes disclosure. Present when and only when the obligation’s configuration selects a managed-delivery offering; Core (API-delivered) obligations omit every destination and materialization field.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    required_finality: reporting_finality.ReportingFinality
    reconciliation_mode: reporting_reconciliation_mode.ReportingReconciliationMode
    reconciliation_status: Annotated[
        ReconciliationStatus,
        Field(
            description='Consumer agreement state for the current required revision. A later superseding revision returns a receipt-required obligation to pending until that revision is accepted.'
        ),
    ]
    health: reporting_health.ReportingHealth
    production_status: Annotated[
        ProductionStatus,
        Field(
            description='Whether any revision has been produced for this obligation. published includes zero-row revisions.'
        ),
    ]
    revision_count: Annotated[
        SchemaInt,
        Field(
            description='Number of revision records for this obligation in the consistent ledger snapshot.',
            ge=0,
        ),
    ]
    consumer_status_count: Annotated[
        SchemaInt | None,
        Field(
            description='Complete number of immutable authenticated consumer status statements associated with this obligation in the ledger snapshot, whether originally joined by reporting_obligation_id or by the exact configuration-generation, report-definition, and period key before the obligation existed. Core status-sync history is counted independently from Reconciled Billing receipts.',
            ge=0,
        ),
    ] = None
    current_consumer_status_id: Annotated[
        str | None,
        Field(
            description='Current unsuperseded consumer status statement associated with this obligation by seller ID or its exact logical period key. Omitted when consumer_status_count is zero.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ] = None
    adjustment_count: Annotated[
        SchemaInt | None,
        Field(
            description='Number of immutable post-official reporting adjustment records for this obligation in the consistent ledger snapshot.',
            ge=0,
        ),
    ] = None
    materialization_count: Annotated[
        SchemaInt | None,
        Field(
            description="Number of materialization records for this obligation's revisions in the consistent ledger snapshot. Present iff the obligation is managed-delivery (destination_ref present).",
            ge=0,
        ),
    ] = None
    successful_materialization_count: Annotated[
        SchemaInt | None,
        Field(
            description='Number of available/delivered verified materializations in the consistent ledger snapshot. Present iff the obligation is managed-delivery (destination_ref present).',
            ge=0,
        ),
    ] = None
    receipt_count: Annotated[
        SchemaInt | None,
        Field(
            description='Complete number of authenticated receipts associated with this obligation in the ledger snapshot. Present iff reconciliation_mode is consumer_receipt.',
            ge=0,
        ),
    ] = None
    accepted_receipt_count: Annotated[
        SchemaInt | None,
        Field(
            description='Number of accepted receipts. At most one current accepted receipt per consumer and revision contributes to reconciliation_status. Present iff reconciliation_mode is consumer_receipt.',
            ge=0,
        ),
    ] = None
    adjustment_receipt_count: Annotated[
        SchemaInt | None,
        Field(
            description="Number of authenticated receipts for adjustments targeting this obligation's official revision. Reconciled Billing only.",
            ge=0,
        ),
    ] = None
    accepted_adjustment_receipt_count: Annotated[
        SchemaInt | None,
        Field(
            description='Number of accepted adjustment receipts. Reconciled Billing buyers do not post an adjustment until their exact digest is accepted.',
            ge=0,
        ),
    ] = None
    pending_adjustment_count: Annotated[
        SchemaInt | None,
        Field(
            description='Number of applicable adjustments without an accepted receipt. Reconciled Billing complete/healthy requires zero.',
            ge=0,
        ),
    ] = None
    issues: list[reporting_status_issue.ReportingStatusIssue]
    resource_retained_until: Annotated[
        AwareDatetime | None,
        Field(
            description='Minimum time through which at least one verified materialization for a completed obligation remains readable. Managed-delivery only; Core revisions are retained per status_retention_days and readable through the existing API transports.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var accepted_adjustment_receipt_count : int | None
var accepted_receipt_count : int | None
var account_id : str
var adjustment_count : int | None
var adjustment_receipt_count : int | None
var consumer_status_count : int | None
var coverage : ReportingCoverage
var current_consumer_status_id : str | None
var delivery_config_id : str
var delivery_config_version : int
var destination_ref : str | None
var expected_at : pydantic.types.AwareDatetime
var feed_purpose : ReportingFeedPurpose
var health : ReportingHealth
var issues : list[ReportingStatusIssue]
var materialization_count : int | None
var media_buy_ids : list[ReportingMediaBuyId]
var model_config
var pending_adjustment_count : int | None
var period : Period
var production_status : ProductionStatus
var receipt_count : int | None
var reconciliation_mode : ReportingReconciliationMode
var reconciliation_status : ReconciliationStatus
var report_definition_id : str
var reporting_obligation_id : str
var reporting_profile : str
var required_finality : ReportingFinality
var resource_retained_until : pydantic.types.AwareDatetime | None
var revision_count : int
var schedule : ReportingSchedule
var scope_resolved_at : pydantic.types.AwareDatetime
var successful_materialization_count : int | None

Inherited members

class ReportingOrchestration (*args, **kwds)
Expand source code
class ReportingOrchestration(StrEnum):
    producer_managed = 'producer_managed'
    consumer_managed = 'consumer_managed'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var consumer_managed
var producer_managed
class ReportingPackageId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingPackageId(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}
    _json_schema_extra = {'title': 'Reporting Package ID'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingPrimaryKey (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingPrimaryKey(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 128, 'min_length': 1}
    _json_schema_extra = {'title': 'Reporting Primary Key'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingProfile (**data: Any)
Expand source code
class ReportingProfile(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    id: Annotated[str, Field(max_length=128, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,128}$')]
    version: Annotated[str, Field(max_length=64, min_length=1)]
    schema_uri: Annotated[
        AnyUrl,
        Field(
            description='Authenticated seller/provider or AdCP-registry HTTPS origin only; never an IP literal, userinfo URL, redirect target, or mutable validation authority.'
        ),
    ]
    schema_sha256: Annotated[
        str,
        Field(
            description='Digest of the exact schema bytes. SDKs verify this before parsing and cache by digest.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ]
    schema_dialect: Annotated[
        Literal['https://json-schema.org/draft/2020-12/schema'],
        Field(
            description="Closed SDK-bundled dialect. The SDK never resolves a metaschema over the network, and the fetched document's $schema MUST equal this value."
        ),
    ] = 'https://json-schema.org/draft/2020-12/schema'
    schema_ref_policy: Annotated[
        Literal['local_fragment_only'],
        Field(
            description='The fetched schema is a self-contained bundle. Every $ref is a local # fragment; remote and relative-document dependencies are forbidden.'
        ),
    ] = 'local_fragment_only'
    grain: Annotated[
        str,
        Field(
            description='Stable description of what one logical row represents.',
            max_length=128,
            min_length=1,
        ),
    ]
    primary_keys: Annotated[
        list[reporting_canonicalization_contract.ReportingPrimaryKey], Field(min_length=1)
    ]
    canonicalization_id: Annotated[
        str | None,
        Field(
            description='Rules for stable logical row ordering, value encoding, nulls, and schema used by canonical_content_digest.',
            max_length=128,
            min_length=1,
        ),
    ] = None
    canonicalization_contract_version: Literal['1.0'] = '1.0'
    canonicalization_media_type: Literal['application/vnd.adcp.reporting-canonicalization+json'] = (
        'application/vnd.adcp.reporting-canonicalization+json'
    )
    canonicalization_uri: Annotated[
        AnyUrl | None,
        Field(
            description='Retrievable exact canonicalization contract on the authenticated seller/provider or AdCP-registry origin. SDKs apply the same bounded, redirect-free SSRF controls as schema_uri and verify canonicalization_sha256 before use.'
        ),
    ] = None
    canonicalization_sha256: Annotated[
        str | None,
        Field(
            description='Digest of the exact canonicalization contract identified by canonicalization_id.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ] = 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 canonicalization_contract_version : Literal['1.0']
var canonicalization_id : str | None
var canonicalization_media_type : Literal['application/vnd.adcp.reporting-canonicalization+json']
var canonicalization_sha256 : str | None
var canonicalization_uri : pydantic.networks.AnyUrl | None
var grain : str
var id : str
var model_config
var primary_keys : list[ReportingPrimaryKey]
var schema_dialect : Literal['https://json-schema.org/draft/2020-12/schema']
var schema_ref_policy : Literal['local_fragment_only']
var schema_sha256 : str
var schema_uri : pydantic.networks.AnyUrl
var version : str

Inherited members

class ReportingReaderCompatibilityItem (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ReportingReaderCompatibilityItem(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 128, 'min_length': 1}
    _json_schema_extra = {'title': 'Reporting Reader Compatibility Item'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ReportingReceipt (**data: Any)
Expand source code
class ReportingReceipt(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    reporting_receipt_id: Annotated[
        str, Field(max_length=255, min_length=16, pattern='^[A-Za-z0-9_.:-]{16,255}$')
    ]
    reporting_obligation_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_revision_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_materialization_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    supersedes_reporting_receipt_id: Annotated[
        str | None,
        Field(
            description="Optional immutable rejected receipt replaced by this new receipt. It MUST name the caller's current rejected receipt for this obligation and revision; accepted current receipts are terminal.",
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ] = None
    status: Status
    verification_profile: reporting_verification_profile.ReportingVerificationProfile
    observed_row_count: Annotated[SchemaInt, Field(ge=0)]
    observed_control_totals: list[reporting_control_total.ReportingControlTotal]
    observed_canonical_content_digest: (
        reporting_canonical_content_digest.ReportingCanonicalContentDigest | None
    ) = None
    observed_manifest_sha256: Annotated[str | None, Field(pattern='^[A-Fa-f0-9]{64}$')] = None
    observed_native_version_ref: (
        reporting_native_version_ref.ReportingNativeVersionReference | None
    ) = None
    consumer_commit_ref: Annotated[
        str | None,
        Field(
            description='Optional non-secret consumer checkpoint, transaction, or load identifier. It is evidence for operations, not authorization or a credential.',
            max_length=512,
            min_length=1,
        ),
    ] = None
    rejection_codes: Annotated[list[RejectionCode] | None, Field(min_length=1)] = None
    observed_at: AwareDatetime
    received_at: AwareDatetime | 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 consumer_commit_ref : str | None
var model_config
var observed_at : pydantic.types.AwareDatetime
var observed_canonical_content_digest : ReportingCanonicalContentDigest | None
var observed_control_totals : list[ReportingControlTotal1 | ReportingControlTotal2]
var observed_manifest_sha256 : str | None
var observed_native_version_ref : ReportingNativeVersionReference | None
var observed_row_count : int
var received_at : pydantic.types.AwareDatetime | None
var rejection_codes : list[RejectionCode] | None
var reporting_materialization_id : str
var reporting_obligation_id : str
var reporting_receipt_id : str
var reporting_revision_id : str
var status : Status
var supersedes_reporting_receipt_id : str | None
var verification_profile : ReportingVerificationProfile

Inherited members

class ReportingReconciliationMode (*args, **kwds)
Expand source code
class ReportingReconciliationMode(StrEnum):
    delivery_only = 'delivery_only'
    consumer_receipt = 'consumer_receipt'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var consumer_receipt
var delivery_only
class ReportingReliabilityMeasurementPeriod (**data: Any)
Expand source code
class ReportingReliabilityMeasurementPeriod(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    start: AwareDatetime
    end: AwareDatetime

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 end : pydantic.types.AwareDatetime
var model_config
var start : pydantic.types.AwareDatetime

Inherited members

class ReportingReliabilityStatistics (**data: Any)
Expand source code
class ReportingReliabilityStatistics(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    offering_id: Annotated[
        str, Field(max_length=128, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,128}$')
    ]
    measurement_period: ReportingReliabilityMeasurementPeriod
    obligations_due: Annotated[
        SchemaInt, Field(description='Denominator for on-time performance.', ge=1)
    ]
    obligations_on_time: Annotated[
        SchemaInt,
        Field(
            description='Obligations whose required revision was published by expected_at. Divide by obligations_due for the on-time rate.',
            ge=0,
        ),
    ]
    official_revisions_published: Annotated[
        SchemaInt, Field(description='Denominator for the official-adjustment rate.', ge=0)
    ]
    official_revisions_adjusted: Annotated[
        SchemaInt,
        Field(
            description='Distinct official revisions receiving at least one adjustment. Divide by official_revisions_published for the adjustment rate.',
            ge=0,
        ),
    ]
    publication_latency_seconds: Annotated[
        LatencyPercentiles,
        Field(
            description='Observed seconds from period.end to publication of the required revision.'
        ),
    ]
    adjustment_latency_seconds: Annotated[
        LatencyPercentiles | None,
        Field(
            description='Observed seconds from official finalized_at to the first adjustment, required when official_revisions_adjusted is nonzero.'
        ),
    ] = None
    adjustment_magnitude: Annotated[
        list[AdjustmentMagnitudeItem] | None,
        Field(
            description='Optional absolute adjustment-magnitude percentiles for comparable control totals such as spend.'
        ),
    ] = None
    evidence: Evidence

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 adjustment_latency_seconds : LatencyPercentiles | None
var adjustment_magnitude : list[AdjustmentMagnitudeItem] | None
var evidence : Evidence
var measurement_period : ReportingReliabilityMeasurementPeriod
var model_config
var obligations_due : int
var obligations_on_time : int
var offering_id : str
var official_revisions_adjusted : int
var official_revisions_published : int
var publication_latency_seconds : LatencyPercentiles

Inherited members

class ReportingReportDefinition (**data: Any)
Expand source code
class ReportingReportDefinition(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    contract_version: Annotated[
        ContractVersion,
        Field(
            description='1.1 adds immutable official closes with adjustments_only correction semantics for Reliable Reporting 1.0. Version 1.0 remains accepted for compatibility with the preceding experimental managed-reporting contract.'
        ),
    ]
    media_type: Literal['application/vnd.adcp.reporting-definition+json'] = 'application/vnd.adcp.reporting-definition+json'
    report_definition_id: Annotated[
        str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ]
    reporting_profile: Annotated[str, Field(max_length=128, min_length=1)]
    grain: Annotated[str, Field(max_length=128, min_length=1)]
    source: Source
    calendar: Calendar
    metrics: Annotated[list[Metric], Field(min_length=1)]
    dimensions: list[Dimension]
    restatement_policy: RestatementPolicy
    finality_policies: Annotated[
        list[FinalityPolicies | FinalityPolicies1 | FinalityPolicies2], Field(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 calendar : Calendar
var contract_version : ContractVersion
var dimensions : list[Dimension]
var finality_policies : list[FinalityPolicies | FinalityPolicies1 | FinalityPolicies2]
var grain : str
var media_type : Literal['application/vnd.adcp.reporting-definition+json']
var metrics : list[Metric]
var model_config
var report_definition_id : str
var reporting_profile : str
var restatement_policy : RestatementPolicy
var source : Source

Inherited members

class ReportingResource (**data: Any)
Expand source code
class ReportingResource(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    resource_ref: Annotated[
        str,
        Field(
            description='Seller-issued opaque reference to this exact authenticated resource descriptor.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    kind: Annotated[
        Kind, Field(description='Shape through which the durable revision is consumed.')
    ]
    location: Annotated[
        str,
        Field(
            description='Non-secret provider-native object, relation, or share identifier. MUST NOT contain an activation URL, signed URL, bearer token, password, private key, or embedded credential.',
            max_length=2048,
            min_length=1,
        ),
    ]
    native_version_ref: reporting_native_version_ref.ReportingNativeVersionReference | None = None
    manifest_version: Annotated[
        Literal['1.0'],
        Field(description='Version of reporting-file-manifest.json used by a manifest resource.'),
    ] = '1.0'
    manifest_sha256: Annotated[
        str | None,
        Field(
            description='SHA-256 over the exact manifest bytes. Consumers verify this before parsing the manifest.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ] = None
    immutability: Annotated[
        Immutability,
        Field(description='How this descriptor selects the exact immutable materialization.'),
    ]
    expires_at: Annotated[
        AwareDatetime,
        Field(
            description='Mandatory finite lower-bound endpoint through which this exact resource remains resolvable; it cannot be earlier than the advertised retention contract.'
        ),
    ]
    reader_compatibility: Annotated[
        list[ReportingReaderCompatibilityItem] | None,
        Field(
            description='Reader features or format constraints required to consume this resource. Readiness verification MUST use a representative supported reader.'
        ),
    ] = 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 expires_at : pydantic.types.AwareDatetime
var immutability : Immutability
var kind : Kind
var location : str
var manifest_sha256 : str | None
var manifest_version : Literal['1.0']
var model_config
var native_version_ref : ReportingNativeVersionReference | None
var reader_compatibility : list[ReportingReaderCompatibilityItem] | None
var resource_ref : str

Inherited members

class ReportingRevision (**data: Any)
Expand source code
class ReportingRevision(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    reporting_revision_id: Annotated[
        str,
        Field(
            description='Portable AdCP identity for this immutable report publication. Distinct from package delivery_revision_id and provider-native versions.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    revision_content_sha256: Annotated[
        str,
        Field(
            description='SHA-256 of the immutable RFC 8785 JCS binding object containing reporting_revision_id, row_count, control_totals, and reporting_rows. Reliable Reporting 1.0 Core revisions include it and exact reads return the identical value.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ]
    report_definition_id: Annotated[
        str,
        Field(
            description='Identity or canonical fingerprint of immutable metric, grain, attribution, breakdown, action-definition, profile, and calendar/timezone semantics.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    report_definition_uri: AnyUrl
    report_definition_sha256: Annotated[str, Field(pattern='^[A-Fa-f0-9]{64}$')]
    reporting_profile: Annotated[str, Field(max_length=128, min_length=1)]
    schema_version: Annotated[str, Field(max_length=64, min_length=1)]
    schema_uri: Annotated[
        AnyUrl,
        Field(
            description='Machine-readable schema on the authenticated seller/provider or AdCP-registry origin.'
        ),
    ]
    schema_sha256: Annotated[
        str,
        Field(
            description='Digest of the exact schema bytes used to validate this immutable revision.',
            pattern='^[A-Fa-f0-9]{64}$',
        ),
    ]
    schema_dialect: Annotated[
        Literal['https://json-schema.org/draft/2020-12/schema'],
        Field(description='Closed SDK-bundled dialect; the metaschema is never network-fetched.'),
    ] = 'https://json-schema.org/draft/2020-12/schema'
    schema_ref_policy: Annotated[
        Literal['local_fragment_only'],
        Field(
            description='The fetched schema is self-contained and every $ref is a local # fragment.'
        ),
    ] = 'local_fragment_only'
    account_id: Annotated[str, Field(min_length=1)]
    media_buy_ids: Annotated[
        list[reporting_coverage.ReportingMediaBuyId],
        Field(
            description='Exact frozen media-buy denominator inherited from the obligation, including buys with zero rows. An empty array proves a zero-buy period rather than an unknown denominator.'
        ),
    ]
    coverage: Annotated[
        reporting_coverage.ReportingCoverage,
        Field(
            description='Frozen product/package denominator represented by this logical content. The same coverage follows the revision to every destination.'
        ),
    ]
    period: Annotated[
        Period, Field(description='Half-open reporting interval with its source calendar boundary.')
    ]
    finality: reporting_finality.ReportingFinality
    finality_basis: Annotated[
        FinalityBasis | None,
        Field(
            description='Why an official revision is considered final: an authoritative source signal, a versioned contractual cutoff, or a versioned stabilization rule.'
        ),
    ] = None
    finality_policy_id: Annotated[
        str | None,
        Field(
            description='Immutable policy/version reference that defines the selected finality basis. It MUST be bound by report_definition_id.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    finalized_at: Annotated[
        AwareDatetime | None,
        Field(
            description='When the producer applied the declared finality basis to this official revision.'
        ),
    ] = None
    observed_at: Annotated[
        AwareDatetime,
        Field(description='When the seller obtained or committed this source observation.'),
    ]
    data_through: Annotated[
        AwareDatetime | None,
        Field(
            description='Latest event time conservatively included, or null when precision is unknown.'
        ),
    ]
    data_through_precision: DataThroughPrecision
    supersedes_reporting_revision_id: Annotated[
        str | None,
        Field(
            description='Immediately superseded snapshot revision of the same logical slice. An official revision is terminal and MUST NOT be named here; later corrections use reporting-adjustment records.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    row_count: Annotated[
        SchemaInt,
        Field(
            description='Logical row count, including zero for a successfully evaluated empty report.',
            ge=0,
        ),
    ]
    control_totals: Annotated[
        list[reporting_control_total.ReportingControlTotal],
        Field(
            description='Profile-defined totals computed from the canonical logical revision. Names MUST be unique.'
        ),
    ]
    canonical_content_digest: (
        reporting_canonical_content_digest.ReportingCanonicalContentDigest | None
    ) = None
    created_at: AwareDatetime

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 account_id : str
var canonical_content_digest : ReportingCanonicalContentDigest | None
var control_totals : list[ReportingControlTotal1 | ReportingControlTotal2]
var coverage : ReportingCoverage
var created_at : pydantic.types.AwareDatetime
var data_through : pydantic.types.AwareDatetime | None
var data_through_precision : DataThroughPrecision
var finality : ReportingFinality
var finality_basis : FinalityBasis | None
var finality_policy_id : str | None
var finalized_at : pydantic.types.AwareDatetime | None
var media_buy_ids : list[ReportingMediaBuyId]
var model_config
var observed_at : pydantic.types.AwareDatetime
var period : Period
var report_definition_id : str
var report_definition_sha256 : str
var report_definition_uri : pydantic.networks.AnyUrl
var reporting_profile : str
var reporting_revision_id : str
var revision_content_sha256 : str
var row_count : int
var schema_dialect : Literal['https://json-schema.org/draft/2020-12/schema']
var schema_ref_policy : Literal['local_fragment_only']
var schema_sha256 : str
var schema_uri : pydantic.networks.AnyUrl
var schema_version : str
var supersedes_reporting_revision_id : str | None

Inherited members

class ReportingSchedule (**data: Any)
Expand source code
class ReportingSchedule(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    period_duration: Annotated[
        str,
        Field(
            description='Strictly positive ISO 8601 duration of each reporting period, such as PT15M, P1D, or P1M.',
            pattern='^P(?=.*[1-9])(?=\\d|T)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$',
        ),
    ]
    alignment: ReportingScheduleAlignment
    period_anchor: Annotated[
        AwareDatetime | None,
        Field(
            description='Required for billing_cycle alignment. This immutable instant anchors the recurring half-open billing periods so producer and consumer derive the same month, quarter, or other contractual cycle.'
        ),
    ] = None
    period_timezone: Annotated[
        str | None,
        Field(
            description='Required IANA timezone for source_timezone and billing_cycle calendar arithmetic. A numeric UTC offset is not sufficient because it does not define DST transitions.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    delivery_sla: Annotated[
        str,
        Field(
            description='Non-negative maximum time after period end before the required revision is due. PT0S means due at period close; expected_at equals the resolved period end plus this duration.',
            pattern='^P(?=\\d|T)(?=.*\\d)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$',
        ),
    ]

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 alignment : ReportingScheduleAlignment
var delivery_sla : str
var model_config
var period_anchor : pydantic.types.AwareDatetime | None
var period_duration : str
var period_timezone : str | None

Inherited members

class ReportingScheduleAlignment (*args, **kwds)
Expand source code
class ReportingScheduleAlignment(StrEnum):
    utc = 'utc'
    account_timezone = 'account_timezone'
    source_timezone = 'source_timezone'
    billing_cycle = 'billing_cycle'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var account_timezone
var billing_cycle
var source_timezone
var utc
class ReportingScheduleOffering (**data: Any)
Expand source code
class ReportingScheduleOffering(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    period_duration: Annotated[
        str,
        Field(
            pattern='^P(?=.*[1-9])(?=\\d|T)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$'
        ),
    ]
    alignment: reporting_schedule.ReportingScheduleAlignment
    period_anchor_policy: Annotated[
        PeriodAnchorPolicy | None,
        Field(
            description='For billing_cycle only. fixed requires the advertised anchor and timezone; configurable lets each authorized account configuration select them.'
        ),
    ] = None
    period_timezone_policy: Annotated[
        PeriodTimezonePolicy | None,
        Field(
            description="For source_timezone only. fixed advertises one exact upstream IANA timezone; account_resolved requires the seller to resolve and echo the account's upstream reporting timezone during configuration."
        ),
    ] = None
    period_anchor: AwareDatetime | None = None
    period_timezone: Annotated[str | None, Field(max_length=255, min_length=1)] = None
    delivery_sla: Annotated[
        str,
        Field(
            pattern='^P(?=\\d|T)(?=.*\\d)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$'
        ),
    ]

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 alignment : ReportingScheduleAlignment
var delivery_sla : str
var model_config
var period_anchor : pydantic.types.AwareDatetime | None
var period_anchor_policy : PeriodAnchorPolicy | None
var period_duration : str
var period_timezone : str | None
var period_timezone_policy : PeriodTimezonePolicy | None

Inherited members

class ReportingStatusChangedWebhook (**data: Any)
Expand source code
class ReportingStatusChangedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Sender-generated key stable across retries of the same fire. Sellers MUST generate a cryptographically random value (UUID v4 recommended) per distinct fire and reuse it on every retry. Receivers MUST dedupe by this key, scoped to the authenticated sender identity.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        str,
        Field(
            description='Stable per logical health transition; re-emissions reuse it, and a later distinct transition receives a new id.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    notification_type: Literal['reporting.status_changed'] = 'reporting.status_changed'
    fired_at: AwareDatetime
    subscriber_id: Annotated[
        str,
        Field(
            description='Identifies which account-level notification_configs[] entry is receiving this fire.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    account_id: Annotated[str, Field(min_length=1)]
    delivery_config_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    delivery_config_version: Annotated[SchemaInt, Field(ge=1)]
    feed_purpose: reporting_delivery_offering.ReportingFeedPurpose
    reporting_obligation_id: Annotated[
        str | None,
        Field(
            description='Present when the transition is obligation-scoped; absent for configuration-level transitions.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    health: Annotated[
        reporting_health.ReportingHealth,
        Field(description='The health state after this transition.'),
    ]
    previous_health: reporting_health.ReportingHealth | None = None
    issue_ids: Annotated[
        list[IssueId] | None,
        Field(
            description='Stable identifiers of the open issues that caused or survived this transition, matching issues[].issue_id on get_reporting_status, so consumers can project AdCP reporting issues into durable work items. Empty or absent on recovery transitions.',
            max_length=16,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 account_id : str
var delivery_config_id : str
var delivery_config_version : int
var ext : ExtensionObject | None
var feed_purpose : ReportingFeedPurpose
var fired_at : pydantic.types.AwareDatetime
var health : ReportingHealth
var idempotency_key : str
var issue_ids : list[IssueId] | None
var model_config
var notification_id : str
var notification_type : Literal['reporting.status_changed']
var previous_health : ReportingHealth | None
var reporting_obligation_id : str | None
var subscriber_id : str

Inherited members

class ReportingStatusIssue (**data: Any)
Expand source code
class ReportingStatusIssue(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    issue_id: Annotated[
        str,
        Field(
            description='Seller-issued stable identifier for this logical issue: re-emissions and later polls of the same unresolved condition reuse it, and resolution retires it, so consumers can project AdCP reporting issues into durable work items. A recurrence after resolution receives a new id.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ]
    code: Code
    severity: ReportingStatusSeverity
    opened_at: Annotated[
        AwareDatetime | None,
        Field(
            description='When the seller first observed this logical condition, carried unchanged across every re-emission until the issue is retired. It anchors the escalation clock advertised as consumer_mismatch_escalation_seconds and lets a consumer age an issue without keeping its own first-seen table. Required when code is CONSUMER_STATUS_MISMATCH.'
        ),
    ] = None
    issue_state: Annotated[
        IssueState | None,
        Field(
            description='Optional seller-maintained lifecycle for this issue_id. open is the default when omitted. acknowledged means a human on responsible_party has taken it up but the condition persists. resolved means the underlying condition no longer holds; a recurrence uses a new issue_id. waived means the parties agreed off-protocol to disregard this exact issue even though its underlying condition may still hold. Only open and acknowledged issues appear in issues[]; retiring an issue removes it from the projection rather than publishing it at resolved or waived, so a reader that treats a nonempty issues[] as degradation stays correct. A CONSUMER_STATUS_MISMATCH waiver follows the bilateral, exact-scope requirements in consumer_mismatch_lifecycle.'
        ),
    ] = None
    external_ref: Annotated[
        str | None,
        Field(
            description="Optional opaque, non-secret correlation string for the party's own tracker — a ticket key, incident ID, or case number. Untrusted display text only. The character class excludes whitespace and the solidus, so the value cannot express a URL or a sentence; receivers compare, store, and display it as inert text and never dereference, resolve, or execute it. It confers no authorization and MUST NOT be used to look up state across accounts or callers.",
            max_length=128,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,128}$',
        ),
    ] = None
    responsible_party: ResponsibleParty
    recommended_action: RecommendedAction
    message: Annotated[
        str | None,
        Field(
            description='Untrusted display text only. SDKs and agents dispatch exclusively on closed code/recommended_action values and never execute embedded links or instructions.',
            max_length=500,
        ),
    ] = None
    reporting_obligation_id: Annotated[
        str | None, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$')
    ] = None
    reporting_status_id: Annotated[
        str | None,
        Field(
            description='Current authenticated consumer status statement that caused this mismatch.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ] = None
    delivery_config_id: Annotated[
        str | None, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ] = None
    delivery_config_version: Annotated[SchemaInt | None, Field(ge=1)] = None
    feed_purpose: reporting_delivery_offering.ReportingFeedPurpose | None = None
    media_buy_ids: Annotated[
        list[reporting_coverage.ReportingMediaBuyId] | None, Field(min_length=1)
    ] = None
    package_ids: Annotated[
        list[reporting_coverage.ReportingPackageId] | None, Field(min_length=1)
    ] = None
    period_start: AwareDatetime | None = None
    period_end: AwareDatetime | None = None
    expected_at: AwareDatetime | 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 code : Code
var delivery_config_id : str | None
var delivery_config_version : int | None
var expected_at : pydantic.types.AwareDatetime | None
var external_ref : str | None
var feed_purpose : ReportingFeedPurpose | None
var issue_id : str
var issue_state : IssueState | None
var media_buy_ids : list[ReportingMediaBuyId] | None
var message : str | None
var model_config
var opened_at : pydantic.types.AwareDatetime | None
var package_ids : list[ReportingPackageId] | None
var period_end : pydantic.types.AwareDatetime | None
var period_start : pydantic.types.AwareDatetime | None
var recommended_action : RecommendedAction
var reporting_obligation_id : str | None
var reporting_status_id : str | None
var responsible_party : ResponsibleParty
var severity : ReportingStatusSeverity

Inherited members

class ReportingStatusSeverity (*args, **kwds)
Expand source code
class ReportingStatusSeverity(StrEnum):
    delayed = 'delayed'
    action_required = 'action_required'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var action_required
var delayed
class ReportingVerification (**data: Any)
Expand source code
class ReportingVerification(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    verified_at: Annotated[
        AwareDatetime,
        Field(
            description='When the producer completed verification through the claimed consumer/destination path.'
        ),
    ]
    verification_path: Annotated[
        VerificationPath,
        Field(
            description='Path on which verification succeeded. dataset_share readiness requires representative_consumer; delivered warehouse state requires destination.'
        ),
    ]
    verification_profile: reporting_verification_profile.ReportingVerificationProfile
    row_count: Annotated[
        SchemaInt,
        Field(
            description='Verified row count. Zero explicitly distinguishes an empty committed revision from a missing revision.',
            ge=0,
        ),
    ]
    control_totals: Annotated[
        list[reporting_control_total.ReportingControlTotal],
        Field(
            description='Profile-defined totals recomputed through verification_path. Names MUST be unique.'
        ),
    ]
    canonical_content_digest: (
        reporting_canonical_content_digest.ReportingCanonicalContentDigest | None
    ) = None
    physical_checksums: Annotated[
        list[PhysicalChecksums | PhysicalChecksums1] | None,
        Field(
            description='Method-specific byte/object checksums. Different encodings of the same logical revision normally have different values.',
            min_length=1,
        ),
    ] = None
    native_commit_evidence: Annotated[
        NativeCommitEvidence | None,
        Field(
            description='Provider-native immutable version evidence observed through the named consumer or destination path.'
        ),
    ] = 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 canonical_content_digest : ReportingCanonicalContentDigest | None
var control_totals : list[ReportingControlTotal1 | ReportingControlTotal2]
var model_config
var native_commit_evidence : NativeCommitEvidence | None
var physical_checksums : list[PhysicalChecksums | PhysicalChecksums1] | None
var row_count : int
var verification_path : VerificationPath
var verification_profile : ReportingVerificationProfile
var verified_at : pydantic.types.AwareDatetime

Inherited members

class ReportingVerificationProfile (*args, **kwds)
Expand source code
class ReportingVerificationProfile(StrEnum):
    native_commit = 'native_commit'
    manifest_checksums = 'manifest_checksums'
    canonical_digest = 'canonical_digest'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var canonical_digest
var manifest_checksums
var native_commit
class ReportingVerificationProfileSet (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class ReportingVerificationProfileSet(RootModel[list[ReportingVerificationProfileSetEnum]]):
    root: Annotated[
        list[ReportingVerificationProfileSetEnum],
        Field(
            description="Verification profiles the destination can accept. native_commit requires provider-native transaction/version evidence plus counts and control totals; manifest_checksums requires a committed file manifest with cryptographic checksums; canonical_digest requires recomputation of the canonical logical-content digest. A reporting feed selects one profile from this allowed set according to the seller offering and the feed's strictness requirements.",
            min_length=1,
            title='Reporting Verification Profile Set',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[list[ReportingVerificationProfileSetEnum]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[ReportingVerificationProfileSetEnum]
class ReportingVerificationProfileSetEnum (*args, **kwds)
Expand source code
class ReportingVerificationProfileSetEnum(StrEnum):
    native_commit = 'native_commit'
    manifest_checksums = 'manifest_checksums'
    canonical_digest = 'canonical_digest'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var canonical_digest
var manifest_checksums
var native_commit
class ReportingWebhook (**data: Any)
Expand source code
class ReportingWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    url: Annotated[AnyUrl, Field(description='Webhook endpoint URL for reporting notifications')]
    token: Annotated[
        str | None,
        Field(
            description='Optional client-provided token for webhook validation. Echoed back in webhook payload to validate request authenticity.',
            min_length=16,
        ),
    ] = None
    authentication: Annotated[
        Authentication,
        Field(
            deprecated=True,
            description="Legacy authentication configuration for webhook delivery (A2A-compatible). Opts the receiver into Bearer or HMAC-SHA256 signing. Both schemes are deprecated; the preferred signing profile for new integrations is RFC 9421, where the seller signs with a key published at its brand.json agents[] entry and the buyer verifies against the seller's JWKS — no shared secret crosses the wire (see docs/building/implementation/security.mdx#webhook-callbacks). This field is required in AdCP 3.x; the requirement is removed in AdCP 4.0 when the default RFC 9421 path becomes the only path.",
        ),
    ]
    reporting_frequency: Annotated[
        ReportingFrequency,
        Field(
            description='Frequency for automated reporting delivery. Must be supported by all products in the media buy.'
        ),
    ]
    requested_metrics: Annotated[
        list[available_metric.AvailableMetric] | None,
        Field(
            description="Optional list of metrics to include in webhook notifications. If omitted, all available metrics are included; an empty array has the same meaning as omission (it does not narrow to impressions and spend only). impressions and spend are always included regardless of this list. Must be a subset of the product's available_metrics. Subset evaluation and leaf resolution follow `enums/available-metric.json`: a numeric leaf may be covered by its container, while each structured distribution must be explicitly available. Requesting any nested identity selects its canonical carrier inside the payload's nested object. Same narrowing semantics as get_media_buy_delivery's requested_metrics (which additionally requires at least one entry when present)."
        ),
    ] = 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 model_config
var operation_id : str | None
var reporting_frequency : ReportingFrequency
var requested_metrics : list[AvailableMetric] | None
var token : str | None
var url : pydantic.networks.AnyUrl

Instance variables

var authentication : Authentication
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.

Inherited members

class ReportingWriteDestination1 (**data: Any)
Expand source code
class ReportingWriteDestination1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['existing'] = 'existing'
    destination_ref: Annotated[
        str,
        Field(
            description='Seller-issued immutable destination-generation reference returned by sync_agent_configuration, an earlier sync, or bilateral setup.',
            max_length=255,
            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 destination_ref : str
var mode : Literal['existing']
var model_config

Inherited members

class ReportingWriteDestination2 (**data: Any)
Expand source code
class ReportingWriteDestination2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    mode: Literal['provision'] = 'provision'
    provider: Annotated[Provider, Field(description='Platform hosting the destination.')]
    location: Annotated[
        str,
        Field(
            description='Provider-native bucket, prefix, project/dataset, catalog/schema, or equivalent locator. It MUST NOT contain an embedded credential or signed URL.',
            max_length=2048,
            min_length=1,
        ),
    ]
    access_mode: Annotated[
        str | None,
        Field(
            description='Optional provider access family used for capability matching.',
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_.-]*$',
        ),
    ] = 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 access_mode : str | None
var location : str
var mode : Literal['provision']
var model_config
var provider : Provider

Inherited members

class RepresentationDestination (**data: Any)
Expand source code
class RepresentationDestination(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    product_id: Annotated[
        str, Field(description='Product owned by the destination seller.', min_length=1)
    ]
    format_option: Annotated[
        product_format_declaration.ProductFormatDeclaration,
        Field(
            description='Exact effective destination declaration. The full declaration is carried so an option without format_option_id remains addressable. The destination seller verifies it against the current product and applicable placement/publisher narrowings.'
        ),
    ]
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description='Optional placements the derived manifest must satisfy. Omission means every placement in the intended product route, not an unconstrained destination.',
            min_length=1,
        ),
    ] = None
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST execution version selected for seller-assembled first-class VAST trackers when no sibling exact-version VAST document supplies it. Must be accepted by format_option and is preserved in selection lineage.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST execution version selected for seller-assembled first-class DAAST trackers when no sibling exact-version DAAST document supplies it. Must be accepted by format_option and is preserved in selection lineage.'
        ),
    ] = 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 execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var format_option : ProductFormatDeclaration1 | ProductFormatDeclaration2 | ProductFormatDeclaration3 | ProductFormatDeclaration4 | ProductFormatDeclaration5 | ProductFormatDeclaration6 | ProductFormatDeclaration7 | ProductFormatDeclaration8 | ProductFormatDeclaration9 | ProductFormatDeclaration10 | ProductFormatDeclaration11 | ProductFormatDeclaration12 | ProductFormatDeclaration13 | ProductFormatDeclaration14 | ProductFormatDeclaration15 | ProductFormatDeclaration16
var model_config
var placement_refs : list[PlacementReference] | None
var product_id : str

Inherited members

class RepresentationRejection (**data: Any)
Expand source code
class RepresentationRejection(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    representation_id: Annotated[str, Field(min_length=1)]
    code: Code
    message: Annotated[str, Field(min_length=1)]
    details: 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 code : Code
var details : dict[str, typing.Any] | None
var message : str
var model_config
var representation_id : str

Inherited members

class RepresentationSelection (**data: Any)
Expand source code
class RepresentationSelection(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    creative_id: Annotated[str, Field(min_length=1)]
    revision_id: creative_revision_id.CreativeRevisionId
    revision_content_digest: Annotated[
        str,
        Field(
            description='Verified digest from the complete source representation set. A downstream seller uses this value, not the selected manifest bytes alone, to enforce immutable revision reuse.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    selected_representation_id: Annotated[str, Field(min_length=1)]
    strategy: Annotated[
        representation_selection_strategy.RepresentationSelectionStrategy,
        Field(description='Deterministic strategy applied after compatibility filtering.'),
    ]
    selected_output_digest: Annotated[
        str,
        Field(
            description='Digest of the derived seller-bound manifest projection, computed with RFC 8785 JCS after removing exactly top-level `$schema`, `representation_selection`, `creative_id`, `revision_id`, `name`, `tags`, `status`, `weight`, `placement_refs`, `placement_ids`, and `inputs`. Every other field, including unknown delivery fields, is included. The identical exclusion list applies to the returned CreativeManifest and its later CreativeAsset sync wrapper. A selected sync item cannot carry localization in this version. This is the review/execution fingerprint for the projection, distinct from revision_content_digest, which binds the complete source set.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    execution_vast_version: Annotated[
        vast_version.VastVersion | None,
        Field(
            description='Exact VAST version verified for seller-assembled first-class VAST trackers. This is selection lineage and part of the execution review identity; it is not included in selected_output_digest.'
        ),
    ] = None
    execution_daast_version: Annotated[
        daast_version.DaastVersion | None,
        Field(
            description='Exact DAAST version verified for seller-assembled first-class DAAST trackers. This is selection lineage and part of the execution review identity; it is not included in selected_output_digest.'
        ),
    ] = None
    resolved_by: Annotated[
        ResolvedBy,
        Field(
            description='Who performed deterministic compatibility resolution. A buyer may resolve locally from seller discovery. Seller resolution is valid only on the destination sales agent when it advertised representation_resolution; an independent creative agent cannot claim seller-bound compatibility.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var creative_id : str
var execution_daast_version : DaastVersion | None
var execution_vast_version : VastVersion | None
var model_config
var resolved_by : ResolvedBy
var revision_content_digest : str
var revision_id : CreativeRevisionId
var selected_output_digest : str
var selected_representation_id : str
var strategy : RepresentationSelectionStrategy

Inherited members

class RequestProposalsInputRequired (**data: Any)
Expand source code
class RequestProposalsInputRequired(CompactTaskInputRequired):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class RequestProposalsSubmitted (**data: Any)
Expand source code
class RequestProposalsSubmitted(CompactTaskSubmitted):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class RequestProposalsWorking (**data: Any)
Expand source code
class RequestProposalsWorking(CompactTaskWorking):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Required (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class Required(RootModel[Literal[True]]):
    root: Literal[True]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Literal[True]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Literal[True]
class RequiredGeoTargetingItem (**data: Any)
Expand source code
class RequiredGeoTargetingItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    level: Annotated[
        geo_level.GeographicTargetingLevel,
        Field(description='Geographic targeting level (country, region, metro, postal_area)'),
    ]
    country: Annotated[
        str | None,
        Field(
            description='ISO 3166-1 alpha-2 country code. Required for native postal_area system filters; not applicable to country, region, or metro filters.',
            pattern='^[A-Z]{2}$',
        ),
    ] = None
    system: Annotated[
        str | None,
        Field(
            description="Optional classification system within the level. Use for a specific metro system (e.g., 'nielsen_dma'), native postal_area system (e.g., 'zip' with country 'US'), or deprecated legacy postal alias (e.g., 'us_zip'). Not applicable for country/region which use ISO standards."
        ),
    ] = 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 country : str | None
var level : GeographicTargetingLevel
var model_config
var system : str | None

Inherited members

class RequiredPerformanceStandard (**data: Any)
Expand source code
class RequiredPerformanceStandard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    metric: performance_standard_metric.PerformanceStandardMetric
    threshold: Annotated[StrictFloat, Field(ge=0.0, le=1.0)]
    standard: viewability_standard.ViewabilityStandard | None = None
    vendor: brand_key.BrandKey

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 metric : PerformanceStandardMetric
var model_config
var standard : ViewabilityStandard | None
var threshold : float
var vendor : BrandKey

Inherited members

class ResolutionModel (*args, **kwds)
Expand source code
class ResolutionModel(StrEnum):
    direct_targeting = 'direct_targeting'
    seller_planned = 'seller_planned'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var direct_targeting
var seller_planned
class ResolvedAssets (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class ResolvedAssets(
    RootModel[
        dict[
            Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')],
            localized_creative_asset.LocalizedCreativeAsset | ResolvedAssets1,
        ]
    ]
):
    root: Annotated[
        dict[
            Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')],
            localized_creative_asset.LocalizedCreativeAsset | ResolvedAssets1,
        ],
        Field(description='Complete resolved assets for this locale, keyed by creative slot.'),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[dict[Annotated[str, StringConstraints], Union[LocalizedCreativeAsset, ResolvedAssets1]]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : dict[str, LocalizedCreativeAsset | ResolvedAssets1]
class ResolvedAssets1 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class ResolvedAssets1(RootModel[list[localized_creative_asset.LocalizedCreativeAsset]]):
    root: Annotated[list[localized_creative_asset.LocalizedCreativeAsset], Field(min_length=1)]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[list[LocalizedCreativeAsset]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[LocalizedCreativeAsset]
class ResolvedBy (*args, **kwds)
Expand source code
class ResolvedBy(StrEnum):
    buyer = 'buyer'
    seller = 'seller'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var buyer
var seller
class Resolver (**data: Any)
Expand source code
class Resolver(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    resolver_id: Annotated[str, Field(max_length=255, min_length=1, pattern='^[A-Za-z0-9._:-]+$')]
    url: Annotated[
        AnyUrl,
        Field(
            description='Evaluator-configured HTTPS resolver endpoint. Calls use POST with Content-Type application/json and a body containing only credential_id; query-string and path interpolation are forbidden. The evaluator still applies the attestation fetch contract before every call.'
        ),
    ]
    authentication: Annotated[
        Authentication,
        Field(
            description='Whether the resolver is public or uses credentials managed outside AdCP task payloads. Presenter-supplied credentials are never 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

Class variables

var authentication : Authentication
var model_config
var resolver_id : str
var url : pydantic.networks.AnyUrl

Inherited members

class ResourceRef (**data: Any)
Expand source code
class ResourceRef(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    platform_account_id: Annotated[
        str | None,
        Field(
            description='Provider-native advertiser or business account id, when safe to disclose.'
        ),
    ] = None
    identity_id: Annotated[
        str | None,
        Field(
            description='Provider-native creator, page, channel, organization, or profile id, when safe to disclose.'
        ),
    ] = None
    handle: Annotated[
        str | None,
        Field(description='Provider-native public handle for the owning identity, when available.'),
    ] = None
    profile_url: Annotated[
        AnyUrl | None, Field(description='Public URL for the owning identity, when available.')
    ] = None
    post_id: Annotated[
        str | None,
        Field(
            description='Provider-native post id, when the grant is post-scoped or the failed request referenced a specific post.'
        ),
    ] = None
    post_url: Annotated[
        AnyUrl | None, Field(description='Public URL for the referenced post, when available.')
    ] = 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 handle : str | None
var identity_id : str | None
var model_config
var platform_account_id : str | None
var post_id : str | None
var post_url : pydantic.networks.AnyUrl | None
var profile_url : pydantic.networks.AnyUrl | None

Inherited members

class ResponsePayload (**data: Any)
Expand source code
class ResponsePayload(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    typ: Annotated[
        Literal['adcp-response-payload+jws'],
        Field(description='Type discriminator preventing cross-profile replay.'),
    ]
    task: Annotated[Task, Field(description='Designated task whose response payload is signed.')]
    brand_domain: Annotated[
        str,
        Field(
            description='Brand tenant whose policy store produced the answer. The signer MUST derive this from server-side tenant resolution, not caller-supplied request fields.',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='Canonical URL of the responding brand agent entry whose response-signing key verifies this envelope.'
        ),
    ]
    request_hash: Annotated[
        str,
        Field(
            description='sha256: prefix plus unpadded base64url SHA-256 of the canonical request-binding object for this call.',
            pattern='^sha256:[A-Za-z0-9_-]{43}$',
        ),
    ]
    iat: Annotated[SchemaInt, Field(description='Issued-at time as Unix epoch seconds.', ge=0)]
    exp: Annotated[
        SchemaInt,
        Field(
            description='Expiration time as Unix epoch seconds. Online verifiers reject envelopes after this time, allowing only implementation-defined clock skew.',
            ge=0,
        ),
    ]
    response: Annotated[
        dict[str, Any],
        Field(
            description='Canonical task-body success response payload being attested. Any unsigned task-body fields on the outer response, excluding signed_response and protocol/version envelope fields, MUST match this object.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var brand_domain : str
var exp : int
var iat : int
var model_config
var request_hash : str
var response : dict[str, typing.Any]
var task : Task
var typ : Literal['adcp-adcp.types.domains.core.response-payload+jws']

Inherited members

class ResponsePayloadJwsEnvelope (**data: Any)
Expand source code
class ResponsePayloadJwsEnvelope(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    protected: Annotated[
        str,
        Field(
            description='Base64url-encoded JWS protected header. The decoded header MUST include alg, kid, and typ: adcp-response-payload+jws, and MUST NOT include the RFC 7797 b64 header. Verifiers enforce the key purpose by resolving kid to a JWK with adcp_use: response-signing.',
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]
    payload: Annotated[
        ResponsePayload,
        Field(
            description='Decoded signed payload. Signers compute the JWS payload bytes from the RFC 8785/JCS canonicalization of this object.'
        ),
    ]
    signature: Annotated[
        str,
        Field(
            description='Base64url-encoded JWS signature over the protected header and canonicalized payload.',
            pattern='^[A-Za-z0-9_-]+$',
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var payload : ResponsePayload
var protected : str
var signature : str

Inherited members

class ResponsibleParty (*args, **kwds)
Expand source code
class ResponsibleParty(StrEnum):
    buyer = 'buyer'
    seller = 'seller'
    provider = 'provider'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var buyer
var provider
var seller
class Responsive (**data: Any)
Expand source code
class Responsive(AdCPBaseModel):
    width: StrictBool
    height: StrictBool

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var height : bool
var model_config
var width : bool

Inherited members

class RestatementPolicy (**data: Any)
Expand source code
class RestatementPolicy(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    source_requery_duration: Annotated[
        str,
        Field(
            pattern='^P(?=\\d|T)(?=.*\\d)(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+S)?)?$'
        ),
    ]
    emit_only_on_content_change: Literal[True]
    official_correction_mode: Annotated[
        Literal['adjustments_only'],
        Field(
            description='Once an official revision is published it is immutable and cannot be superseded. Later source corrections are separate reporting-adjustment records applied to a later accounting period.'
        ),
    ] = 'adjustments_only'

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 emit_only_on_content_change : Literal[True]
var model_config
var official_correction_mode : Literal['adjustments_only']
var source_requery_duration : str

Inherited members

class Restriction (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class Restriction(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class RetiredDestination (**data: Any)
Expand source code
class RetiredDestination(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    destination_id: Annotated[
        str, Field(max_length=64, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,64}$')
    ]
    destination_refs: Annotated[
        list[DestinationRef],
        Field(
            description='Retained generation references of the revoked destination, newest first, still resolvable for retained reporting history but ineligible for delivery and for new bindings.',
            max_length=32,
            min_length=1,
        ),
    ]
    revoked_at: AwareDatetime | 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 destination_id : str
var destination_refs : list[DestinationRef]
var model_config
var revoked_at : pydantic.types.AwareDatetime | None

Inherited members

class RightsAgent (**data: Any)
Expand source code
class RightsAgent(AdCPBaseModel):
    url: Annotated[AnyUrl, Field(description='MCP endpoint URL of the rights agent')]
    id: Annotated[str, Field(description='Agent identifier')]

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 id : str
var model_config
var url : pydantic.networks.AnyUrl

Inherited members

class RightsAttestationEvaluation (**data: Any)
Expand source code
class RightsAttestationEvaluation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    rights_id: Annotated[
        str,
        Field(
            description='Rights grant identifier. MUST equal reference.subject.id and evaluation.action_binding.action_id.',
            min_length=1,
        ),
    ]
    content_digest: Annotated[
        str,
        Field(
            description='Digest of the exact rights constraint evaluated. MUST equal reference.subject.content_digest and evaluation.action_binding.action_digest.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    reference: Reference
    evaluation: Evaluation
    ext: ext_1.ExtensionObject | 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 content_digest : str
var evaluation : Evaluation
var ext : ExtensionObject | None
var model_config
var reference : Reference
var rights_id : str

Inherited members

class RightsConstraint (**data: Any)
Expand source code
class RightsConstraint(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    rights_id: Annotated[
        str, Field(description='Rights grant identifier from the acquire_rights response')
    ]
    rights_agent: Annotated[RightsAgent, Field(description='The agent that granted these rights')]
    rights_holder: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description='Canonical BrandRef for the rights holder that issued the grant through an authorized rights agent. Required whenever attestation_refs is present. Evaluators first match this exact BrandRef against local issuer policy, then resolve the authoritative brand.json and bind the credential verification key to exactly one matching agents[] entry with type rights. Sibling-brand agents are never authority. Legacy unattested constraints may omit this field but remain machine-unverified.'
        ),
    ] = None
    valid_from: Annotated[
        AwareDatetime | None, Field(description='Start of the rights validity period')
    ] = None
    valid_until: Annotated[
        AwareDatetime | None,
        Field(
            description='End of the rights validity period. Creative should not be served after this time.'
        ),
    ] = None
    uses: Annotated[
        list[right_use.RightUse],
        Field(description='Rights uses covered by this constraint', min_length=1),
    ]
    countries: Annotated[
        list[Country] | None,
        Field(
            description='Countries where this creative may be served under these rights (ISO 3166-1 alpha-2). If omitted, no country restriction. When both countries and excluded_countries are present, the effective set is countries minus excluded_countries.'
        ),
    ] = None
    excluded_countries: Annotated[
        list[ExcludedCountry] | None,
        Field(
            description='Countries excluded from rights availability (ISO 3166-1 alpha-2). Use when the grant is worldwide except specific markets.'
        ),
    ] = None
    impression_cap: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum total impressions allowed for the full validity period (valid_from to valid_until). This is the absolute cap across all creatives using this rights grant, not a per-creative or per-period limit.',
            ge=1,
        ),
    ] = None
    right_type: Annotated[
        right_type_1.RightType | None,
        Field(
            description='Type of rights (talent, music, etc.). Helps identify constraints when a creative combines multiple rights types.'
        ),
    ] = None
    approval_status: Annotated[
        ApprovalStatus | None,
        Field(
            description='Approval status from the rights holder at manifest creation time (snapshot, not a live value)'
        ),
    ] = None
    grant_status: Annotated[
        GrantStatus | None,
        Field(
            description='Authoritative lifecycle state bound into the grant digest and credential status evidence. Only active can evaluate to verified. paused and revoked credentials are ineligible for serving; resumption issues a fresh active credential and reference.'
        ),
    ] = None
    restrictions: Annotated[
        list[Restriction] | None,
        Field(
            description='Normalized enforceable content and usage restrictions issued with the grant. When present these values are part of content_digest and cannot be omitted or changed without invalidating the attestation.',
            min_length=1,
        ),
    ] = None
    disclosure: Annotated[
        Disclosure | None,
        Field(
            description='Disclosure obligation issued with the grant and bound by content_digest.'
        ),
    ] = None
    creative_approval_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether each creative produced under this grant requires holder approval before distribution. This enforceable term is bound by content_digest.'
        ),
    ] = None
    verification_url: Annotated[
        AnyUrl | None,
        Field(
            deprecated=True,
            description='DEPRECATED legacy informational locator. It is not proof of grant status, a revocation source, a credential locator, or permission to make a network request. Receivers MUST NOT fetch it during rights evaluation, and HTTP status codes have no AdCP authorization meaning. Rights authorization uses attestation_refs and a verifier-of-record evaluation under evaluator-owned policy.',
        ),
    ] = None
    content_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of UTF8(JCS(rights_constraint minus content_digest, attestation_refs, and verification_url)), formatted as sha256:<lowercase hex>. This binds all serving-relevant grant fields, including future extension fields, while deliberately excluding the legacy non-authoritative URL.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    attestation_refs: Annotated[
        list[AttestationRef] | None,
        Field(
            description='Alternative portable presentations of a holder-issued rights-grant credential signed by its authorized rights agent. The buyer carries references only; the serving party remains verifier-of-record. At least one reference must evaluate to verified and match rights_holder, rights_id, rights_agent, content_digest, validity, revocation state, and local policy before this constraint can contribute to serving eligibility.',
            max_length=4,
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 approval_status : ApprovalStatus | None
var attestation_refs : list[AttestationRef] | None
var content_digest : str | None
var countries : list[Country] | None
var creative_approval_required : bool | None
var disclosure : Disclosure | None
var excluded_countries : list[ExcludedCountry] | None
var ext : ExtensionObject | None
var grant_status : GrantStatus | None
var impression_cap : int | None
var model_config
var restrictions : list[Restriction] | None
var right_type : RightType | None
var rights_agent : RightsAgent
var rights_holder : BrandReference | None
var rights_id : str
var uses : list[RightUse]
var valid_from : pydantic.types.AwareDatetime | None
var valid_until : pydantic.types.AwareDatetime | None
var verification_url : pydantic.networks.AnyUrl | None

Inherited members

class Roas (**data: Any)
Expand source code
class Roas(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    value: Annotated[
        StrictFloat,
        Field(
            description='Return per unit of ad spend; 4 means 4 units of value per 1 unit spent.',
            gt=0.0,
        ),
    ]
    strength: Annotated[
        Strength1,
        Field(
            description='`floor` prefers underdelivery to knowingly optimizing below the requested return; `target` optimizes around the requested return. Neither guarantees realized return.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var strength : Strength1
var value : float

Inherited members

class RoasStrength (*args, **kwds)
Expand source code
class RoasStrength(StrEnum):
    floor = 'floor'
    target = 'target'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var floor
var target
class Role2 (*args, **kwds)
Expand source code
class Role2(StrEnum):
    style_reference = 'style_reference'
    product_shot = 'product_shot'
    mood_board = 'mood_board'
    example_creative = 'example_creative'
    logo = 'logo'
    strategy_doc = 'strategy_doc'
    storyboard = 'storyboard'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var example_creative
var mood_board
var product_shot
var storyboard
var strategy_doc
var style_reference
class RotationMode (*args, **kwds)
Expand source code
class RotationMode(StrEnum):
    weighted = 'weighted'
    even = 'even'
    sequential = 'sequential'
    random = 'random'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var even
var random
var sequential
var weighted
class Route (**data: Any)
Expand source code
class Route(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    format_option_id: Annotated[
        str,
        Field(
            description='Format option in this adagents.json placement for which the delegation applies. It MUST resolve through the same-file top-level formats[] catalog or an inline placement format declaration.',
            min_length=1,
        ),
    ]
    capability_id: Annotated[
        str,
        Field(
            description="Agent-local preview capability advertised by the delegated provider. The provider's canonical format declaration MUST satisfy the resolved placement format option.",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]
    covers_placement_presentation: Annotated[
        StrictBool | None,
        Field(
            description="True only when the publisher delegates both creative rendering and the complete placement-specific frame to this route. When false or omitted, consumers compose any presentation_ref around the provider's creative render."
        ),
    ] = False

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var capability_id : str
var covers_placement_presentation : bool | None
var format_option_id : str
var model_config

Inherited members

class Salary (**data: Any)
Expand source code
class Salary(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    min: Annotated[StrictFloat | None, Field(description='Minimum salary.', ge=0.0)] = None
    max: Annotated[StrictFloat | None, Field(description='Maximum salary.', ge=0.0)] = None
    currency: Annotated[str, Field(description='ISO 4217 currency code.', pattern='^[A-Z]{3}$')]
    period: Annotated[Period, Field(description='Pay period.')]

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 currency : str
var max : float | None
var min : float | None
var model_config
var period : Period

Inherited members

class SampleRate (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class SampleRate(ScalarInt):
    __slots__ = ()
    _constraints = {'ge': 1}

An int generated from a JSON Schema integer root.

Validates the way SchemaInt validates an integer field: strict, so "1" and True are refused, with a float carrying no fractional part narrowed to int because JSON Schema counts it as one.

Ancestors

  • adcp.types._scalar.ScalarInt
  • adcp.types._scalar._ScalarRoot
  • builtins.int
class Sandbox (*args, **kwds)
Expand source code
class Sandbox(StrEnum):
    none = 'none'
    iframe = 'iframe'
    safeframe = 'safeframe'
    fencedframe = 'fencedframe'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var fencedframe
var iframe
var none
var safeframe
class ScalarBinding (**data: Any)
Expand source code
class ScalarBinding(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['scalar'] = 'scalar'
    asset_id: Annotated[
        str,
        Field(
            description="The asset_id from the format's assets array. Identifies which individual template slot this binding applies to."
        ),
    ]
    catalog_field: Annotated[
        str,
        Field(
            description="Dot-notation path to the field on the catalog item (e.g., 'name', 'price.amount', 'location.city')."
        ),
    ]
    ext: ext_1.ExtensionObject | 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 asset_id : str
var catalog_field : str
var ext : ExtensionObject | None
var kind : Literal['scalar']
var model_config

Inherited members

class ScanType (*args, **kwds)
Expand source code
class ScanType(StrEnum):
    progressive = 'progressive'
    interlaced = 'interlaced'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var interlaced
var progressive
class ScopeCapability (**data: Any)
Expand source code
class ScopeCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    fixed: Annotated[
        PolicyProfile | None,
        Field(description='Policies supported when budget allocation is fixed or omitted.'),
    ] = None
    seller_optimized: Annotated[
        PolicyProfile | None,
        Field(description='Policies supported when budget_allocation.mode is seller_optimized.'),
    ] = 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 fixed : PolicyProfile | None
var model_config
var seller_optimized : PolicyProfile | None

Inherited members

class ScopeName (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ScopeName(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^custom:[a-z][a-z0-9_]*$'}
    _json_schema_extra = {
        'description': 'Agent-defined scope name, prefixed with `custom:`. Any vendor agent (media-buy seller, signals agent, governance agent, creative agent, brand agent) MAY define custom scopes. Callers MUST NOT assume any semantics from a custom-prefixed scope name.',
        'title': 'CustomScope',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class ScopedCreativeApproval (**data: Any)
Expand source code
class ScopedCreativeApproval(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    scope: Annotated[
        indicator_scope.IndicatorScope,
        Field(description='Publisher or placement to which this approval outcome applies.'),
    ]
    approval_status: creative_approval_status.CreativeApprovalStatus
    rejection_reason: Annotated[
        str | None, Field(description='Human-readable explanation when this scope is rejected.')
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var approval_status : CreativeApprovalStatus
var model_config
var rejection_reason : str | None
var scope : IndicatorScope

Inherited members

class Selector (**data: Any)
Expand source code
class Selector(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    country: Annotated[str, Field(pattern='^[A-Z]{2}$')]
    system: Annotated[str, Field(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 country : str
var model_config
var system : str

Inherited members

class SellerAgentReference (**data: Any)
Expand source code
class SellerAgentReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[
        AnyUrl,
        Field(
            description="The seller agent's API endpoint URL as declared in the property publisher's adagents.json `authorized_agents[].url`. MUST use the `https://` scheme. Receivers compare this URL against the `authorized_agents` list using the AdCP URL canonicalization rules — not byte-equality — and reject mismatches with `seller_not_authorized`. See docs/reference/url-canonicalization."
        ),
    ]
    id: Annotated[
        str | None,
        Field(
            description='Reserved for a future registry-assigned stable seller identifier. Not used today — senders MUST NOT populate this field until a registry is defined. When a future release populates both `agent_url` and `id`, `agent_url` remains authoritative and `id` is advisory.',
            min_length=1,
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var id : str | None
var model_config

Inherited members

class Severity (*args, **kwds)
Expand source code
class Severity(StrEnum):
    error = 'error'
    warning = 'warning'
    info = 'info'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var error
var info
var warning
class Signal (**data: Any)
Expand source code
class Signal(SignalListing):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(
            description='Canonical signal reference for this wholesale signal. New events SHOULD use signal_ref.'
        ),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    signal_agent_segment_id: Annotated[
        str,
        Field(description='Opaque activation handle returned by the signals agent.', min_length=1),
    ]
    name: Annotated[str, Field(description='Human-readable signal name', min_length=1)]
    description: Annotated[str, Field(description='Detailed signal description', min_length=1)]
    value_type: signal_value_type.SignalValueType | None = None
    categories: Annotated[list[str] | None, Field(min_length=1)] = None
    range: Range | None = None
    signal_type: signal_catalog_type.SignalAvailabilityType
    data_provider: Annotated[str | None, Field(min_length=1)] = None
    coverage_percentage: Annotated[
        StrictFloat | None,
        Field(
            deprecated=True,
            description='DEPRECATED for detailed planning. Optional legacy scalar percentage of audience coverage retained only as a fallback for clients that do not consume coverage_forecast. When coverage_forecast is present, coverage_forecast is authoritative for signal-level discovery and coverage_percentage is fallback-only.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    coverage_forecast: Annotated[
        signal_coverage_forecast.SignalCoverageForecast | None,
        Field(
            description='Optional forecast-shaped signal availability guidance using the same wire shape as get_signals.signals[].coverage_forecast. When present, this is authoritative for signal-level discovery coverage.'
        ),
    ] = None
    deployments: Annotated[Sequence[deployment.Deployment], Field(min_length=1)]
    pricing_options: Annotated[
        list[vendor_pricing_option.VendorPricingOption] | None, Field(min_length=1)
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var categories : list[str] | None
var coverage_forecast : SignalCoverageForecast | None
var coverage_percentage : float | None
var data_provider : str | None
var deployments : Sequence[Deployment1 | Deployment2]
var description : str
var model_config
var name : str
var pricing_options : list[VendorPricingOption7 | VendorPricingOption8 | VendorPricingOption9 | VendorPricingOption10 | VendorPricingOption11] | None
var range : Range | None
var signal_agent_segment_id : str
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var signal_type : SignalAvailabilityType
var value_type : SignalValueType | None

Inherited members

class SignalCoverageForecast (**data: Any)
Expand source code
class SignalCoverageForecast(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    points: Annotated[
        list[Point],
        Field(
            description='Coverage or availability points. Each point reuses the standard ForecastPoint shape, MUST include a signal dimension, and MUST include metrics.coverage_rate. Use metrics.impressions for count denominators and metrics.coverage_rate for the fraction of the declared scope represented by the point.',
            min_length=1,
        ),
    ]
    forecast_range_unit: Annotated[
        Literal['availability'],
        Field(
            description="How to interpret the points array. Signal coverage forecasts always use 'availability' because the points describe available inventory or population coverage, not spend curves or temporal pacing."
        ),
    ] = 'availability'
    method: Annotated[
        forecast_method.ForecastMethod,
        Field(description='Method used to produce this coverage forecast.'),
    ]
    scope: Annotated[
        Scope,
        Field(
            description='Explicit denominator for the coverage forecast. This identifies the inventory, product, account, or custom universe that coverage_rate values are relative to. Additional seller-specific qualifiers are allowed for scopes such as line item type, ad server, inventory class, country, or flight window.'
        ),
    ]
    bucket_semantics: Annotated[
        BucketSemantics,
        Field(
            description="'exclusive' means the returned signal-value buckets do not overlap with each other. 'overlapping' means one impression or user can appear in multiple returned buckets, so coverage_rate values may sum above 1.0. This field describes overlap among returned buckets; bucket_completeness declares whether the returned buckets cover the full denominator."
        ),
    ]
    bucket_completeness: Annotated[
        BucketCompleteness,
        Field(
            description="'complete' means the returned buckets cover the declared denominator. For complete + exclusive forecasts, count metrics and coverage_rate values can be treated as a full partition, subject to metric additivity rules. 'partial' means omitted denominator share represents undisclosed, other, or unsupported buckets; buyers MUST NOT infer totals by summing returned points."
        ),
    ]
    generated_at: Annotated[
        AwareDatetime | None, Field(description='When this coverage forecast was computed.')
    ] = None
    valid_until: Annotated[
        AwareDatetime | None, Field(description='When this coverage forecast expires.')
    ] = None
    ext: ext_1.ExtensionObject | 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 bucket_completeness : BucketCompleteness
var bucket_semantics : BucketSemantics
var ext : ExtensionObject | None
var forecast_range_unit : Literal['availability']
var generated_at : pydantic.types.AwareDatetime | None
var method : ForecastMethod
var model_config
var points : list[Point]
var scope : Scope
var valid_until : pydantic.types.AwareDatetime | None

Inherited members

class SignalDefinition (**data: Any)
Expand source code
class SignalDefinition(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    id: Annotated[
        str,
        Field(
            description="Signal identifier within the publishing domain's adagents.json signals[]",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]
    name: Annotated[
        str, Field(description='Human-readable signal name', max_length=255, min_length=1)
    ]
    description: Annotated[
        str | None,
        Field(
            description="Detailed description of what this signal represents and how it's derived",
            max_length=2000,
        ),
    ] = None
    value_type: Annotated[
        signal_value_type.SignalValueType,
        Field(description="The data type of this signal's values"),
    ]
    tags: Annotated[
        list[Tag] | None,
        Field(
            description="Tags for grouping and filtering this domain's published signal definitions"
        ),
    ] = None
    allowed_values: Annotated[
        list[str] | None,
        Field(
            description='For categorical signals, the valid values users can be assigned',
            min_length=1,
        ),
    ] = None
    restricted_attributes: Annotated[
        list[restricted_attribute.RestrictedAttribute] | None,
        Field(
            description="Restricted attribute categories this signal touches. Data providers SHOULD declare these so governance agents can structurally match signals against a plan's restricted_attributes without relying on semantic inference from the signal name or description.",
            min_length=1,
        ),
    ] = None
    demographic_predicate: Annotated[
        demographic_predicate_1.DemographicPredicate | None,
        Field(
            description='Authoritative machine-readable demographic meaning for this signal. Signal names and taxonomy labels alone never establish exact demographic equivalence. Signals carrying this field MUST also declare restricted_attributes including age.'
        ),
    ] = None
    policy_categories: Annotated[
        list[str] | None,
        Field(
            description="Policy categories this signal is sensitive for (e.g., a children's interest signal declares ['children_directed']). Governance agents match these against a plan's policy_categories to flag sensitive data usage.",
            min_length=1,
        ),
    ] = None
    range: Annotated[
        Range | None, Field(description='For numeric signals, the valid value range')
    ] = None
    taxonomy: Annotated[
        Taxonomy | None,
        Field(
            description='Optional taxonomy metadata describing what this signal means in an external audience, content, retail-media, or provider-owned taxonomy. Taxonomy metadata does not create a new value_type and does not change package targeting grammar: buyers still target the named signal according to value_type. When a taxonomy value is a parent node, parent/descendant expansion is seller behavior and must be declared through parent_match_behavior rather than assumed.'
        ),
    ] = None
    segmentation_criteria: Annotated[
        str | None,
        Field(
            description='Rules governing inclusion of identifiers in the segment. Aligns with IAB Data Transparency Standard audience criteria disclosure.',
            max_length=500,
        ),
    ] = None
    criteria_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional URL to a longer-form methodology or criteria document. This is a disclosure pointer; buyers should not branch programmatically on the linked content.'
        ),
    ] = None
    data_sources: Annotated[
        list[DataSource] | None,
        Field(
            description="Origin categories of the raw data used to compile the signal, aligned with IAB Data Transparency Standard source disclosure. Use 'panel' for respondent-panel or JIC-style audience sources. Offline and public-record sources require onboarder disclosure. Co-viewing projection and reconciliation of seller claims against a JIC or measurement vendor belong in measurement reporting/vendor metrics rather than package signal targeting.",
            min_length=1,
        ),
    ] = None
    methodology: Annotated[
        Methodology | None,
        Field(
            description="How the signal's audience membership or attribute was determined. 'modeled' requires the modeling block."
        ),
    ] = None
    audience_expansion: Annotated[
        StrictBool | None,
        Field(
            description='Whether look-alike or similar-audience expansion was used to include additional identifiers. When true, modeling is required.'
        ),
    ] = None
    device_expansion: Annotated[
        StrictBool | None,
        Field(
            description="Whether the signal was expanded deterministically across devices of the same user, household, or business. Probabilistic cross-device expansion is modeling and should use methodology 'modeled' or the modeling block."
        ),
    ] = None
    refresh_cadence: Annotated[
        RefreshCadence | None,
        Field(
            description="Cadence at which the signal definition's underlying segment membership is refreshed."
        ),
    ] = None
    lookback_window: Annotated[
        RefreshCadence | None,
        Field(description='Time window in which a qualifying event can occur for inclusion.'),
    ] = None
    onboarder: Annotated[
        Onboarder | None,
        Field(
            description='Onboarder disclosure. Required when data_sources includes an offline_* or public_record_* source.'
        ),
    ] = None
    subject_type: Annotated[
        audience_subject_type.AudienceSubjectType | None,
        Field(description='What kind of subject this signal characterizes.'),
    ] = None
    resolution_method: Annotated[
        audience_resolution_method.AudienceResolutionMethod | None,
        Field(description='How the subject is resolved at decision time.'),
    ] = None
    id_types: Annotated[
        list[IdType] | None,
        Field(
            description='Identifier currencies analyzed to determine audience membership or attributes.',
            min_length=1,
        ),
    ] = None
    audience_scope: Annotated[
        AudienceScope | None,
        Field(
            description="Context within which the audience attribute was determined. 'single_domain' requires originating_domain."
        ),
    ] = None
    originating_domain: Annotated[
        str | None,
        Field(
            description="Domain of the digital property where the audience originates. Required when audience_scope is 'single_domain'.",
            pattern='^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]{0,61}[A-Za-z0-9])$',
        ),
    ] = None
    countries: Annotated[
        list[Country] | None,
        Field(
            description="ISO 3166-1 alpha-2 country codes where the signal is applicable. Sellers must not expose a signal for media buys in countries outside this list. Federating agents that surface a peer's signal MUST treat the peer-published list as an upper bound, re-check it against the buyer's intended deployment countries, and may apply only narrower local policy.",
            min_length=1,
        ),
    ] = None
    consent_basis: Annotated[
        list[consent_basis_1.ConsentBasis] | None,
        Field(
            description="Declared GDPR Article 6 lawful basis or consent basis under which this signal's data is processed. For non-GDPR regimes, use countries, policy_categories, and disclosure fields to describe jurisdiction-specific obligations unless a future enum value applies.",
            min_length=1,
        ),
    ] = None
    art9_basis: Annotated[
        Art9Basis | None,
        Field(
            description='GDPR Article 9 basis when restricted_attributes is non-empty and the signal is used in jurisdictions where Article 9 applies. Required by policy for applicable use cases rather than universally required at schema level because sensitivity and lawful basis are jurisdiction-relative.'
        ),
    ] = None
    modeling: Annotated[
        Modeling | None,
        Field(
            description="Modeling disclosure for modeled data signals. Required when methodology is 'modeled' or audience_expansion is true. This describes data modeling and intentionally does not reuse creative provenance, which is content/render oriented."
        ),
    ] = None
    data_subject_rights: Annotated[
        DataSubjectRights | None,
        Field(
            description='Per-signal data-subject-rights routing. Inline on the signal because upstream source, rights routing, and response commitments can differ by segment or may be unavailable from a public provider document for custom/private signals. This is a contact/routing reference, not a machine-callable AdCP API.'
        ),
    ] = None
    last_updated: Annotated[
        AwareDatetime | None,
        Field(
            description='When this definition record was last updated. This indicates freshness of the definition record, not an attestation that the underlying data or model was refreshed at that time.'
        ),
    ] = None
    dts_compliant_version: Annotated[
        str | None,
        Field(
            description='IAB Data Transparency Standard version this signal definition self-attests as satisfying, when applicable.'
        ),
    ] = 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 allowed_values : list[str] | None
var art9_basis : Art9Basis | None
var audience_expansion : bool | None
var audience_scope : AudienceScope | None
var consent_basis : list[ConsentBasis] | None
var countries : list[Country] | None
var criteria_url : pydantic.networks.AnyUrl | None
var data_sources : list[DataSource] | None
var data_subject_rights : DataSubjectRights | None
var demographic_predicate : DemographicPredicate | None
var description : str | None
var device_expansion : bool | None
var dts_compliant_version : str | None
var id : str
var id_types : list[IdType] | None
var last_updated : pydantic.types.AwareDatetime | None
var lookback_window : RefreshCadence | None
var methodology : Methodology | None
var model_config
var modeling : Modeling | None
var name : str
var onboarder : Onboarder | None
var originating_domain : str | None
var policy_categories : list[str] | None
var range : Range | None
var refresh_cadence : RefreshCadence | None
var resolution_method : AudienceResolutionMethod | None
var restricted_attributes : list[RestrictedAttribute] | None
var segmentation_criteria : str | None
var subject_type : AudienceSubjectType | None
var tags : list[Tag] | None
var taxonomy : Taxonomy | None
var value_type : SignalValueType

Inherited members

class SignalDefinitionEnrichment (**data: Any)
Expand source code
class SignalDefinitionEnrichment(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    restricted_attributes: Annotated[
        list[restricted_attribute.RestrictedAttribute] | None,
        Field(description='Restricted attribute categories this signal touches.', min_length=1),
    ] = None
    demographic_predicate: Annotated[
        demographic_predicate_1.DemographicPredicate | None,
        Field(
            description="Projected authoritative demographic meaning for the signal. When projected from another provider, this MUST match the provider's definition exactly. Signal names alone never establish demographic semantics."
        ),
    ] = None
    policy_categories: Annotated[
        list[str] | None,
        Field(description='Policy categories this signal is sensitive for.', min_length=1),
    ] = None
    taxonomy: Annotated[
        Taxonomy | None,
        Field(
            description='Optional taxonomy metadata describing what this signal means in an external audience, content, retail-media, or provider-owned taxonomy.'
        ),
    ] = None
    segmentation_criteria: Annotated[str | None, Field(max_length=500)] = None
    criteria_url: AnyUrl | None = None
    data_sources: Annotated[list[DataSource] | None, Field(min_length=1)] = None
    methodology: Methodology | None = None
    audience_expansion: StrictBool | None = None
    device_expansion: StrictBool | None = None
    refresh_cadence: RefreshCadence | None = None
    lookback_window: RefreshCadence | None = None
    onboarder: Onboarder | None = None
    countries: Annotated[list[Country] | None, Field(min_length=1)] = None
    consent_basis: Annotated[
        list[consent_basis_1.ConsentBasis] | None,
        Field(
            description="Data provider's declared GDPR Article 6 lawful basis or consent basis for the underlying signal definition, projected into this get_signals response row when requested. Sellers and federating agents that pass through another provider's signal MUST NOT substitute their own processing basis for the provider-declared basis.",
            min_length=1,
        ),
    ] = None
    art9_basis: Annotated[
        Art9Basis | None,
        Field(
            description="Data provider's declared GDPR Article 9 basis for the underlying signal definition when special-category data is involved and Article 9 applies, projected into this get_signals response row when requested. Sellers and federating agents that pass through another provider's signal MUST NOT substitute their own Article 9 basis for the provider-declared basis."
        ),
    ] = None
    modeling: Modeling | None = None
    data_subject_rights: Annotated[
        DataSubjectRights | None,
        Field(
            description='Per-signal data-subject-rights routing. This is a contact/routing reference, not a machine-callable AdCP API.'
        ),
    ] = None
    last_updated: Annotated[
        AwareDatetime | None,
        Field(
            description='When this definition record was last updated. This indicates freshness of the definition record, not an attestation that the underlying data or model was refreshed at that time.'
        ),
    ] = None
    dts_compliant_version: str | 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 art9_basis : Art9Basis | None
var audience_expansion : bool | None
var consent_basis : list[ConsentBasis] | None
var countries : list[Country] | None
var criteria_url : pydantic.networks.AnyUrl | None
var data_sources : list[DataSource] | None
var data_subject_rights : DataSubjectRights | None
var demographic_predicate : DemographicPredicate | None
var device_expansion : bool | None
var dts_compliant_version : str | None
var last_updated : pydantic.types.AwareDatetime | None
var lookback_window : RefreshCadence | None
var methodology : Methodology | None
var model_config
var modeling : Modeling | None
var onboarder : Onboarder | None
var policy_categories : list[str] | None
var refresh_cadence : RefreshCadence | None
var restricted_attributes : list[RestrictedAttribute] | None
var segmentation_criteria : str | None
var taxonomy : Taxonomy | None

Inherited members

class SignalFilters (**data: Any)
Expand source code
class SignalFilters(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_types: Annotated[
        list[signal_catalog_type.SignalAvailabilityType] | None,
        Field(description='Filter by catalog type', min_length=1),
    ] = None
    data_providers: Annotated[
        list[str] | None, Field(description='Filter by specific data providers', min_length=1)
    ] = None
    max_cpm: Annotated[
        StrictFloat | None,
        Field(description="Maximum CPM filter. Applies only to signals with model='cpm'.", ge=0.0),
    ] = None
    max_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Maximum percent-of-media rate filter. Signals where all percent_of_media pricing options exceed this value are excluded. Does not account for max_cpm caps.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    min_coverage_percentage: Annotated[
        StrictFloat | None, Field(description='Minimum coverage requirement', ge=0.0, le=100.0)
    ] = None
    ext: Annotated[
        ext_1.ExtensionObject | None,
        Field(
            description='Vendor-namespaced extension parameters for seller- or platform-specific signal filter criteria not covered by standard fields. Keys MUST be namespaced under a vendor or platform key (e.g., ext.gam, ext.platform_x). Sellers MUST treat all values as untrusted buyer input; avoid unbounded logging or labels, and do not interpolate values into caller-visible error strings, LLM prompts, SQL queries, or system commands without sanitization. Persistent use of an extension key across multiple buyers is a signal to propose standardization.'
        ),
    ] = 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 catalog_types : list[SignalAvailabilityType] | None
var data_providers : list[str] | None
var ext : ExtensionObject | None
var max_cpm : float | None
var max_percent : float | None
var min_coverage_percentage : float | None
var model_config

Inherited members

class SignalForecastDimension (**data: Any)
Expand source code
class SignalForecastDimension(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Annotated[Literal['signal'], Field(description='Dimension family discriminator.')] = 'signal'
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(
            description='Canonical signal reference for this forecast row. Required when the row needs to disambiguate product-local, data-provider, or signal-source identity. Product-relative forecasts SHOULD use signal_ref.'
        ),
    ] = None
    signal_id: Annotated[
        str | None,
        Field(
            description='Signal identifier shorthand for this forecast row. Use only when the enclosing context already identifies the signal unambiguously, such as a coverage_forecast nested directly under one get_signals signal item. Otherwise use signal_ref.',
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ] = None
    signal_value: Annotated[
        str | StrictFloat | StrictBool | None,
        Field(
            description="Signal value bucket represented by this point. Use null with presence 'absent' to represent inventory where the signal is not present. Omit when the row describes any present value rather than one specific value."
        ),
    ] = None
    presence: Annotated[
        Presence,
        Field(
            description="Whether the signal is present for this point. Use 'absent' for the explicit not-present bucket."
        ),
    ]
    signal_name: Annotated[
        str | None,
        Field(
            description='Human-readable signal name, useful when the buyer has not resolved the signal definition.'
        ),
    ] = None
    signal_value_name: Annotated[
        str | None, Field(description='Human-readable label for the signal value bucket.')
    ] = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> SignalForecastDimension:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('signal_ref',), ('signal_id',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'SignalForecastDimension requires at least one of these field groups: signal_ref | signal_id'
        )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var kind : Literal['signal']
var model_config
var presence : Presence
var signal_id : str | None
var signal_name : str | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var signal_value : str | float | bool | None
var signal_value_name : str | None

Inherited members

class SignalId8 (**data: Any)
Expand source code
class SignalId8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    source: Annotated[
        Literal['catalog'],
        Field(
            description="Discriminator indicating this signal is from a data provider's published adagents.json signals[]"
        ),
    ] = 'catalog'
    data_provider_domain: Annotated[
        str,
        Field(
            description="Domain of the data provider that owns this signal (e.g., 'pinnacle-data.example'). The signal definition is published at this domain's /.well-known/adagents.json",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    id: Annotated[
        str,
        Field(
            description="Signal identifier within the data provider's catalog (e.g., 'likely_ev_buyers', 'income_100k_plus')",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]

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 data_provider_domain : str
var id : str
var model_config
var source : Literal['adcp.types.domains.core.catalog']

Inherited members

class SignalId9 (**data: Any)
Expand source code
class SignalId9(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    source: Annotated[
        Literal['agent'],
        Field(
            description="Discriminator indicating this signal is native to the signal source identified by agent_url, not from a data provider's published signal definitions."
        ),
    ] = 'agent'
    agent_url: Annotated[
        AnyUrl,
        Field(
            description="URL of the signal source that provides this signal (e.g., 'https://signals.example/.well-known/adcp/signals')"
        ),
    ]
    id: Annotated[
        str,
        Field(
            description="Signal identifier within the agent's signal set (e.g., 'custom_auto_intenders')",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var id : str
var model_config
var source : Literal['agent']

Inherited members

class SignalListing (**data: Any)
Expand source code
class SignalListing(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(
            description="Canonical signal reference. Use scope 'product' for a product-local signal defined by this listing; use scope 'data_provider' with data_provider_domain for a signal defined in a data provider's published adagents.json signals[]; use scope 'signal_source' with signal_source_url for a source-native signal."
        ),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older Signals Protocol clients.',
        ),
    ] = None
    name: Annotated[
        str | None,
        Field(
            description="Human-readable signal name. Required when signal_ref.scope is 'product'. For data_provider and signal_source refs, this is optional contextual display text; the referenced definition or source remains authoritative."
        ),
    ] = None
    description: Annotated[
        str | None,
        Field(
            description='Detailed signal description. For data_provider and signal_source refs, this is optional contextual display text and MUST NOT replace the referenced definition.'
        ),
    ] = None
    methodology_url: Annotated[
        AnyUrl | None,
        Field(
            description='Optional link to published methodology, media-kit, or data documentation. For data_provider and signal_source refs, this SHOULD match or supplement the referenced definition.'
        ),
    ] = None
    last_updated: Annotated[
        AwareDatetime | None,
        Field(
            description='When this listing record was last updated. This indicates freshness of the listing record, not an attestation that the underlying data or model was refreshed at that time.'
        ),
    ] = None
    value_type: Annotated[
        signal_value_type.SignalValueType | None,
        Field(
            description="The data type of this signal's values. Required when signal_ref.scope is 'product'."
        ),
    ] = None
    categories: Annotated[
        list[str] | None,
        Field(
            description="Valid values for categorical signals. Present when value_type is 'categorical'.",
            min_length=1,
        ),
    ] = None
    range: Annotated[
        Range | None,
        Field(description="Valid range for numeric signals. Present when value_type is 'numeric'."),
    ] = None
    restricted_attributes: Annotated[
        list[restricted_attribute.RestrictedAttribute] | None,
        Field(
            description='Restricted attribute categories this listing touches. Required with demographic_predicate and must include age. For referenced provider/source signals, any projected values must match the authoritative definition.',
            min_length=1,
        ),
    ] = None
    demographic_predicate: Annotated[
        demographic_predicate_1.DemographicPredicate | None,
        Field(
            description='Machine-readable demographic meaning. For product-local signals this listing is authoritative; for data-provider and signal-source refs, any projected value MUST match the referenced authoritative definition. Signal names alone never establish demographic semantics.'
        ),
    ] = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> SignalListing:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('signal_ref',), ('signal_id',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'SignalListing requires at least one of these field groups: signal_ref | signal_id'
        )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var categories : list[str] | None
var demographic_predicate : DemographicPredicate | None
var description : str | None
var last_updated : pydantic.types.AwareDatetime | None
var methodology_url : pydantic.networks.AnyUrl | None
var model_config
var name : str | None
var range : Range | None
var restricted_attributes : list[RestrictedAttribute] | None
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var value_type : SignalValueType | None

Inherited members

class SignalModelingDisclosure (**data: Any)
Expand source code
class SignalModelingDisclosure(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    required: Annotated[
        StrictBool,
        Field(
            description="The provider's claim that a modeling or AI-use disclosure is required for this signal in at least one applicable jurisdiction. This is a declared compliance signal, not a protocol-level legal determination."
        ),
    ]
    jurisdictions: Annotated[
        list[Jurisdiction] | None,
        Field(
            description='Jurisdictions where a modeling or AI-use disclosure applies.', min_length=1
        ),
    ] = None
    notes: Annotated[
        str | None,
        Field(
            description='Optional provider notes on how the disclosure should be interpreted. Informational only; buyers should not branch programmatically on this text.',
            max_length=2000,
        ),
    ] = 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 jurisdictions : list[Jurisdiction] | None
var model_config
var notes : str | None
var required : bool

Inherited members

class SignalPricingOption (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class SignalPricingOption(RootModel[vendor_pricing_option.VendorPricingOption]):
    root: Annotated[
        vendor_pricing_option.VendorPricingOption,
        Field(
            description='Deprecated — use vendor-pricing-option.json for new implementations. This alias is retained for backward compatibility.',
            title='Signal Pricing Option',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Annotated[Union[VendorPricingOption7, VendorPricingOption8, VendorPricingOption9, VendorPricingOption10, VendorPricingOption11], FieldInfo(annotation=NoneType, required=True, title='Vendor Pricing Option', description='A pricing option offered by a vendor agent (signals, creative, governance). Combines pricing_option_id with the pricing model fields. Pass pricing_option_id in report_usage for billing verification. All vendor discovery responses return pricing_options as an array — vendors may offer multiple options (volume tiers, context-specific rates, different models per product line).')]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : VendorPricingOption7 | VendorPricingOption8 | VendorPricingOption9 | VendorPricingOption10 | VendorPricingOption11
class SignalRef1 (**data: Any)
Expand source code
class SignalRef1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    scope: Annotated[
        Literal['product'],
        Field(
            description="Discriminator indicating the signal resolves through the selected product's included_signals or signal_targeting_options."
        ),
    ] = 'product'
    signal_id: Annotated[
        str,
        Field(
            description='Product-local signal identifier. For local signals exposed on both get_signals and get_products, this MUST match get_signals.signals[].signal_ref.signal_id for the same signal.',
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var scope : Literal['adcp.types.domains.core.product']
var signal_id : str

Inherited members

class SignalRef2 (**data: Any)
Expand source code
class SignalRef2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    scope: Annotated[
        Literal['data_provider'],
        Field(
            description="Discriminator indicating the signal resolves through a data provider's published adagents.json signals[]."
        ),
    ] = 'data_provider'
    data_provider_domain: Annotated[
        str,
        Field(
            description='Domain that publishes the signal definition in its adagents.json signals[].',
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ]
    signal_id: Annotated[
        str,
        Field(
            description="Signal identifier within the data provider's published adagents.json signals[].",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]

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 data_provider_domain : str
var model_config
var scope : Literal['data_provider']
var signal_id : str

Inherited members

class SignalRef3 (**data: Any)
Expand source code
class SignalRef3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    scope: Annotated[
        Literal['signal_source'],
        Field(
            description='Discriminator indicating the signal resolves through the issuing signal source.'
        ),
    ] = 'signal_source'
    signal_source_url: Annotated[
        AnyUrl, Field(description='URL of the signal source that issues this source-native signal.')
    ]
    signal_id: Annotated[
        str,
        Field(
            description="Signal identifier within the issuing signal source's signal set.",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var scope : Literal['signal_source']
var signal_id : str
var signal_source_url : pydantic.networks.AnyUrl

Inherited members

class SignalSelectionGroupRule (**data: Any)
Expand source code
class SignalSelectionGroupRule(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    selection_group: Annotated[
        str,
        Field(
            description='ProductSignalTargetingOption.selection_group value this rule applies to.'
        ),
    ]
    targeting_mode: Annotated[
        TargetingMode | None,
        Field(
            description="How options in this selection_group are intended to be used in signal_targeting_groups. 'include' maps to child groups with operator 'any'. 'exclude' maps to child groups with operator 'none'. Omit when options in the group may be used according to each option's allowed_targeting_modes."
        ),
    ] = None
    selection_mode: Annotated[
        SelectionMode | None,
        Field(
            description="Selection behavior for this selection_group. 'required' means at least min_selected_signals, or 1 when omitted. 'fixed' means default_selected options in this group are seller-applied and read-only."
        ),
    ] = None
    min_selected_signals: Annotated[
        SchemaInt | None,
        Field(
            description="Minimum selected options from this selection_group. If selection_mode is 'required' and omitted, sellers MUST treat the minimum as 1.",
            ge=0,
        ),
    ] = None
    max_selected_signals: Annotated[
        SchemaInt | None,
        Field(description='Maximum selected options from this selection_group.', 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

Class variables

var max_selected_signals : int | None
var min_selected_signals : int | None
var model_config
var selection_group : str
var selection_mode : SelectionMode | None
var targeting_mode : TargetingMode | None

Inherited members

class SignalTag (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class SignalTag(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-z0-9_-]+$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class SignalTargeting1 (**data: Any)
Expand source code
class SignalTargeting1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New targeting constraints SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[Literal['binary'], Field(description='Discriminator for binary signals')] = 'binary'
    value: Annotated[
        StrictBool,
        Field(
            description='Whether to include (true) or exclude (false) users matching this signal'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var value : bool
var value_type : Literal['binary']

Inherited members

class SignalTargeting2 (**data: Any)
Expand source code
class SignalTargeting2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New targeting constraints SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[
        Literal['categorical'], Field(description='Discriminator for categorical signals')
    ] = 'categorical'
    values: Annotated[
        list[str],
        Field(
            description='Values to target. Users with any of these values will be included.',
            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 model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var value_type : Literal['categorical']
var values : list[str]

Inherited members

class SignalTargeting3 (**data: Any)
Expand source code
class SignalTargeting3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New targeting constraints SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[
        Literal['numeric'], Field(description='Discriminator for numeric signals')
    ] = 'numeric'
    min_value: Annotated[
        StrictFloat | None,
        Field(
            description="Minimum value (inclusive). Omit for no minimum. Must be <= max_value when both are provided. Should be >= signal's range.min if defined."
        ),
    ] = None
    max_value: Annotated[
        StrictFloat | None,
        Field(
            description="Maximum value (inclusive). Omit for no maximum. Must be >= min_value when both are provided. Should be <= signal's range.max if defined."
        ),
    ] = 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 max_value : float | None
var min_value : float | None
var model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var value_type : Literal['numeric']

Inherited members

class SignalTargetingExpression1 (**data: Any)
Expand source code
class SignalTargetingExpression1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[signal_ref_1.SignalRef, Field(description='Named signal being targeted.')]
    value_type: Annotated[Literal['binary'], Field(description='Discriminator for binary signals.')] = 'binary'
    value: Annotated[
        Literal[True],
        Field(
            description='Binary package signal entries match users for whom the signal is true. Use the parent group operator for include/exclude.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3
var value : Literal[True]
var value_type : Literal['binary']

Inherited members

class SignalTargetingExpression2 (**data: Any)
Expand source code
class SignalTargetingExpression2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[signal_ref_1.SignalRef, Field(description='Named signal being targeted.')]
    value_type: Annotated[
        Literal['categorical'], Field(description='Discriminator for categorical signals.')
    ] = 'categorical'
    values: Annotated[
        list[str],
        Field(
            description='Values to target. Users with any of these values match the expression.',
            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 model_config
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3
var value_type : Literal['categorical']
var values : list[str]

Inherited members

class SignalTargetingExpression3 (**data: Any)
Expand source code
class SignalTargetingExpression3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[signal_ref_1.SignalRef, Field(description='Named signal being targeted.')]
    value_type: Annotated[
        Literal['numeric'], Field(description='Discriminator for numeric signals.')
    ] = 'numeric'
    min_value: Annotated[
        StrictFloat | None,
        Field(
            description="Minimum value, inclusive. Omit for no minimum. Should be within the signal definition's range when declared."
        ),
    ] = None
    max_value: Annotated[
        StrictFloat | None,
        Field(
            description="Maximum value, inclusive. Omit for no maximum. Should be within the signal definition's range when declared."
        ),
    ] = 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 max_value : float | None
var min_value : float | None
var model_config
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3
var value_type : Literal['numeric']

Inherited members

class SignalTargetingItem1 (**data: Any)
Expand source code
class SignalTargetingItem1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New targeting constraints SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[Literal['binary'], Field(description='Discriminator for binary signals')] = 'binary'
    value: Annotated[
        StrictBool,
        Field(
            description='Whether to include (true) or exclude (false) users matching this signal'
        ),
    ]

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 model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var value : bool
var value_type : Literal['binary']

Inherited members

class SignalTargetingItem2 (**data: Any)
Expand source code
class SignalTargetingItem2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New targeting constraints SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[
        Literal['categorical'], Field(description='Discriminator for categorical signals')
    ] = 'categorical'
    values: Annotated[
        list[str],
        Field(
            description='Values to target. Users with any of these values will be included.',
            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

Subclasses

Class variables

var model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var value_type : Literal['categorical']
var values : list[str]

Inherited members

class SignalTargetingItem3 (**data: Any)
Expand source code
class SignalTargetingItem3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    signal_ref: Annotated[
        signal_ref_1.SignalRef | None,
        Field(description='The signal to target. New targeting constraints SHOULD use signal_ref.'),
    ] = None
    signal_id: Annotated[
        signal_id_1.SignalId | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_ref instead. Legacy SignalId retained for compatibility with older clients.',
        ),
    ] = None
    value_type: Annotated[
        Literal['numeric'], Field(description='Discriminator for numeric signals')
    ] = 'numeric'
    min_value: Annotated[
        StrictFloat | None,
        Field(
            description="Minimum value (inclusive). Omit for no minimum. Must be <= max_value when both are provided. Should be >= signal's range.min if defined."
        ),
    ] = None
    max_value: Annotated[
        StrictFloat | None,
        Field(
            description="Maximum value (inclusive). Omit for no maximum. Must be >= min_value when both are provided. Should be <= signal's range.max if defined."
        ),
    ] = 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 max_value : float | None
var min_value : float | None
var model_config
var signal_id : SignalId8 | SignalId9 | None
var signal_ref : SignalRef1 | SignalRef2 | SignalRef3 | None
var value_type : Literal['numeric']

Inherited members

class SignalTargetingItem4 (**data: Any)
Expand source code
class SignalTargetingItem4(AdCPBaseModel):
    targeting_mode: Annotated[
        TargetingMode | None,
        Field(
            description="Desired use of this signal on the product. 'include' requires the product option to allow use in an any group. 'exclude' requires the product option to allow use in a none group."
        ),
    ] = TargetingMode.include

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 model_config
var targeting_mode : TargetingMode | None

Inherited members

class SignalTargetingItem5 (**data: Any)
Expand source code
class SignalTargetingItem5(SignalTargetingItem1, SignalTargetingItem4):
    targeting_mode: Annotated[
        TargetingMode | None,
        Field(
            description="Desired use of this signal on the product. 'include' requires the product option to allow use in an any group. 'exclude' requires the product option to allow use in a none group."
        ),
    ] = TargetingMode.include

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var targeting_mode : TargetingMode | None

Inherited members

class SignalTargetingItem6 (**data: Any)
Expand source code
class SignalTargetingItem6(SignalTargetingItem2, SignalTargetingItem4):
    targeting_mode: Annotated[
        TargetingMode | None,
        Field(
            description="Desired use of this signal on the product. 'include' requires the product option to allow use in an any group. 'exclude' requires the product option to allow use in a none group."
        ),
    ] = TargetingMode.include

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var targeting_mode : TargetingMode | None

Inherited members

class SignalTargetingItem7 (**data: Any)
Expand source code
class SignalTargetingItem7(SignalTargetingItem3, SignalTargetingItem4):
    targeting_mode: Annotated[
        TargetingMode | None,
        Field(
            description="Desired use of this signal on the product. 'include' requires the product option to allow use in an any group. 'exclude' requires the product option to allow use in a none group."
        ),
    ] = TargetingMode.include

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var targeting_mode : TargetingMode | None

Inherited members

class SignalTargetingRules (**data: Any)
Expand source code
class SignalTargetingRules(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    resolution_model: Annotated[
        ResolutionModel | None,
        Field(
            description="How selected signal_targeting_options are resolved against the product's inventory. 'direct_targeting' means selected signals are applied as targeting predicates to the package inventory. 'seller_planned' means selected signals are planning inputs that the seller resolves against product-specific inventory, timing, availability, reach, or pacing constraints; buyers SHOULD NOT attempt to decompose the signal selection into lower-level inventory or schedule decisions. Use 'seller_planned' for products such as linear broadcast schedules where the audience definition may be portable but the audience-to-avails plan is seller-resolved."
        ),
    ] = ResolutionModel.direct_targeting
    selection_mode: Annotated[
        SelectionMode | None,
        Field(
            description="Default selection behavior for selectable signals on this product. 'optional' means the buyer may select zero or more signals. 'required' means the buyer must select at least min_selected_signals, or 1 when min_selected_signals is omitted. 'fixed' means the seller applies the default_selected signals and the buyer cannot add or remove them; buyers SHOULD render those entries as read-only and sellers MUST echo them in package targeting_overlay.signal_targeting_groups. Use selection_group_rules for product-scoped products that need different behavior for different groups, such as fixed suppressions plus a required include tier."
        ),
    ] = SelectionMode.optional
    min_selected_signals: Annotated[
        SchemaInt | None,
        Field(
            description="Minimum number of signals the buyer must select when selection_mode is 'required'. If selection_mode is 'required' and this field is omitted, sellers MUST treat the minimum as 1. Defaults to 0 for optional selection.",
            ge=0,
        ),
    ] = None
    max_selected_signals: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of signals the buyer may select for a package. Omit when there is no declared limit beyond the available options.',
            ge=1,
        ),
    ] = None
    max_selected_per_group: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of signal_targeting_options the buyer may select from the same ProductSignalTargetingOption.selection_group. Use 1 for mutually exclusive alternatives within each option group. This limit applies to product option grouping, not to the number of child groups in packages[].targeting_overlay.signal_targeting_groups.',
            ge=1,
        ),
    ] = None
    max_signal_targeting_groups: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of child groups allowed in packages[].targeting_overlay.signal_targeting_groups.groups. Omit when the seller has no declared limit beyond product terms.',
            ge=1,
        ),
    ] = None
    max_signals_per_targeting_group: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of signals allowed in each packages[].targeting_overlay.signal_targeting_groups.groups[].signals array. Omit when the seller has no declared limit beyond product terms.',
            ge=1,
        ),
    ] = None
    selection_group_rules: Annotated[
        list[signal_selection_group_rule.SignalSelectionGroupRule] | None,
        Field(
            description='Optional product-scoped overrides for specific ProductSignalTargetingOption.selection_group values. Use this when one product has mixed behavior, such as fixed seller-applied suppressions, a required pick-one include tier, optional buyer-selected exclusions, or heterogeneous targeting planes that must be represented as separate ANDed clauses. Rules apply only to options whose selection_group matches. When selection_group_rules are present, each packages[].targeting_overlay.signal_targeting_groups child group MUST contain signals from exactly one selection_group and one targeting_mode, and buyers MUST send at most one child group for each (selection_group, targeting_mode) pair. Sellers MUST reject duplicate, mixed, or collapsed groups that combine distinct selection_group_rules into the same child group.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var max_selected_per_group : int | None
var max_selected_signals : int | None
var max_signal_targeting_groups : int | None
var max_signals_per_targeting_group : int | None
var min_selected_signals : int | None
var model_config
var resolution_model : ResolutionModel | None
var selection_group_rules : list[SignalSelectionGroupRule] | None
var selection_mode : SelectionMode | None

Inherited members

class SlaWindow (**data: Any)
Expand source code
class SlaWindow(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
        regex_engine="python-re",
    )
    response_max: Annotated[
        str | None,
        Field(
            description='Maximum elapsed time from when the buyer issues the action to when the seller acknowledges receipt (mode-appropriate: synchronous response for self_serve, tolerance decision for conditional_self_serve, or queue acknowledgement for seller_managed and legacy requires_approval). Sellers include weekends and non-working periods in the maximum. ISO 8601 duration.',
            examples=['PT5M', 'PT4H', 'P1D'],
            pattern='^P(?!$)(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$',
        ),
    ] = None
    completion_max: Annotated[
        str | None,
        Field(
            description='Maximum elapsed time from buyer issuing the action to the seller completing it (mutation applied, proposal finalized, or seller-managed decision resolved). Sellers include weekends and non-working periods in the maximum. ISO 8601 duration.',
            examples=['PT1H', 'PT24H', 'P2D'],
            pattern='^P(?!$)(\\d+Y)?(\\d+M)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$',
        ),
    ] = 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 completion_max : str | None
var model_config
var response_max : str | None

Inherited members

class Sort (**data: Any)
Expand source code
class Sort(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    field: Annotated[Field1 | None, Field(description='Field to sort by')] = Field1.created_at
    direction: Annotated[
        sort_direction.SortDirection | None, Field(description='Sort direction')
    ] = sort_direction.SortDirection.desc

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 direction : SortDirection | None
var field : Field1 | None
var model_config

Inherited members

class SortApplied (**data: Any)
Expand source code
class SortApplied(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    field: str
    direction: Direction

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 direction : Direction
var field : str
var model_config

Inherited members

class Special (**data: Any)
Expand source code
class Special(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    name: Annotated[
        str, Field(description="Name of the event (e.g., 'Olympics 2028', 'Super Bowl LXI')")
    ]
    category: Annotated[
        special_category.SpecialCategory | None, Field(description='Category of the event')
    ] = None
    starts: Annotated[
        AwareDatetime | None, Field(description='When the event starts (ISO 8601)')
    ] = None
    ends: Annotated[
        AwareDatetime | None,
        Field(description='When the event ends (ISO 8601). Omit for single-day events.'),
    ] = 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 category : SpecialCategory | None
var ends : pydantic.types.AwareDatetime | None
var model_config
var name : str
var starts : pydantic.types.AwareDatetime | None

Inherited members

class Specification (**data: Any)
Expand source code
class Specification(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    label: Annotated[str, Field(max_length=60)]
    value: Annotated[str, Field(max_length=200)]

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 label : str
var model_config
var value : str

Inherited members

class SpotReportingCapability (**data: Any)
Expand source code
class SpotReportingCapability(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    available_metrics: Annotated[
        list[available_metric.AvailableMetric],
        Field(
            description='Metrics available at spot grain. A declared metric may be absent from a provisional measurement window and appear when a later window supersedes it. A metric omitted from this declaration is not promised at spot grain even when it is available at package grain.'
        ),
    ]

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 available_metrics : list[AvailableMetric]
var model_config

Inherited members

class StoreItem (**data: Any)
Expand source code
class StoreItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    store_id: Annotated[
        str,
        Field(
            description='Unique identifier for this store. Used to reference specific stores in targeting, inventory feeds, and creative templates.'
        ),
    ]
    name: Annotated[
        str,
        Field(
            description="Human-readable store name (e.g., 'Amsterdam Flagship', 'Brooklyn Heights')."
        ),
    ]
    location: Annotated[Location, Field(description='Geographic coordinates of the store.')]
    address: Annotated[
        Address | None, Field(description='Structured address for display and geocoding fallback.')
    ] = None
    catchments: Annotated[
        list[catchment.Catchment] | None,
        Field(
            description='Catchment areas for this store. Each defines a reachable area using travel time (isochrone), simple radius, or pre-computed GeoJSON. Multiple catchments allow different modes — e.g., 15-minute drive AND 10-minute walk.',
            min_length=1,
        ),
    ] = None
    phone: Annotated[
        str | None, Field(description="Store phone number in E.164 format (e.g., '+31201234567').")
    ] = None
    url: Annotated[
        AnyUrl | None,
        Field(description='Store-specific page URL (e.g., store locator detail page).'),
    ] = None
    hours: Annotated[
        dict[
            Literal['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
            str,
        ]
        | None,
        Field(
            description='Operating hours. Keys are ISO day names (monday–sunday), values are time ranges.'
        ),
    ] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering stores in targeting and creative selection (e.g., 'flagship', 'pickup', 'pharmacy').",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 address : Address | None
var catchments : list[Catchment] | None
var ext : ExtensionObject | None
var hours : dict[typing.Literal['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'], str] | None
var location : Location
var model_config
var name : str
var phone : str | None
var store_id : str
var tags : list[str] | None
var url : pydantic.networks.AnyUrl | None

Inherited members

class Storyboard (**data: Any)
Expand source code
class Storyboard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    storyboard_id: str
    status: StoryboardStatus
    steps_passed: Annotated[SchemaInt | None, Field(ge=0)] = None
    steps_total: Annotated[SchemaInt | None, Field(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

Class variables

var model_config
var status : StoryboardStatus
var steps_passed : int | None
var steps_total : int | None
var storyboard_id : str

Inherited members

class StoryboardStatus (*args, **kwds)
Expand source code
class StoryboardStatus(StrEnum):
    passing = 'passing'
    failing = 'failing'
    partial = 'partial'
    untested = 'untested'
    skipped = 'skipped'
    not_selected = 'not_selected'
    unknown = 'unknown'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var failing
var not_selected
var partial
var passing
var skipped
var unknown
var untested
class Strength (*args, **kwds)
Expand source code
class Strength(StrEnum):
    cap = 'cap'
    target = 'target'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var cap
var target
class Strength1 (*args, **kwds)
Expand source code
class Strength1(StrEnum):
    floor = 'floor'
    target = 'target'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var floor
var target
class StringArray (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class StringArray(RootModel[list[str]]):
    root: list[str]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[list[str]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[str]
class Subject10 (**data: Any)
Expand source code
class Subject10(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['brand'] = 'brand'
    resource_type: Literal['https://adcontextprotocol.org/claims/subjects/rights-grant'] = 'https://adcontextprotocol.org/claims/subjects/rights-grant'
    brand: brand_ref.BrandReference
    ext: ext_1.ExtensionObject | 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 brand : BrandReference
var ext : ExtensionObject | None
var model_config
var resource_type : Literal['https://adcontextprotocol.org/claims/subjects/rights-grant']
var type : Literal['brand']

Inherited members

class Subject11 (**data: Any)
Expand source code
class Subject11(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['brand'] = 'brand'
    brand: brand_ref.BrandReference
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var brand : BrandReference
var ext : ExtensionObject | None
var model_config
var type : Literal['brand']

Inherited members

class Subject12 (**data: Any)
Expand source code
class Subject12(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['agent'] = 'agent'
    agent_url: Annotated[
        AnyUrl, Field(description='Canonical HTTPS endpoint of the agent the claim concerns.')
    ]
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var agent_url : pydantic.networks.AnyUrl
var ext : ExtensionObject | None
var model_config
var type : Literal['agent']

Inherited members

class Subject13 (**data: Any)
Expand source code
class Subject13(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['resource'] = 'resource'
    resource_type: Annotated[
        AnyUrl,
        Field(
            description='Open, absolute URI naming the subject vocabulary, such as https://adcontextprotocol.org/claims/subjects/signal. AdCP does not maintain an exhaustive enum.'
        ),
    ]
    namespace: Annotated[
        AnyUrl,
        Field(
            description='Absolute URI identifying the namespace in which id is unique. This may be an AdCP agent endpoint, a catalog origin, or a domain-specific namespace URI.'
        ),
    ]
    id: Annotated[
        str,
        Field(
            description='Stable identifier for the subject within namespace. It MUST NOT be compared without resource_type and namespace.',
            max_length=1024,
            min_length=1,
        ),
    ]
    content_digest: Annotated[
        str | None,
        Field(
            description='Optional SHA-256 pin for the exact content or immutable snapshot identified by this resource subject. This is part of the complete typed subject identity and is distinct from AttestationReference.content_digest, which pins credential bytes.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var content_digest : str | None
var ext : ExtensionObject | None
var id : str
var model_config
var namespace : pydantic.networks.AnyUrl
var resource_type : pydantic.networks.AnyUrl
var type : Literal['resource']

Inherited members

class Subject14 (**data: Any)
Expand source code
class Subject14(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['resource'] = 'resource'
    resource_type: Literal['https://adcontextprotocol.org/claims/subjects/audience-evidence'] = 'https://adcontextprotocol.org/claims/subjects/audience-evidence'
    content_digest: Annotated[str, Field(pattern='^sha256:[a-f0-9]{64}$')]
    brand: brand_ref.BrandReference
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var brand : BrandReference
var content_digest : str
var ext : ExtensionObject | None
var model_config
var resource_type : Literal['https://adcontextprotocol.org/claims/subjects/audience-evidence']
var type : Literal['resource']

Inherited members

class Subject15 (**data: Any)
Expand source code
class Subject15(Subject11):
    model_config = ConfigDict(
        extra='forbid',
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Subject16 (**data: Any)
Expand source code
class Subject16(Subject12):
    model_config = ConfigDict(
        extra='forbid',
    )
    brand: brand_ref.BrandReference

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 brand : BrandReference
var model_config

Inherited members

class Subject17 (**data: Any)
Expand source code
class Subject17(Subject14):
    model_config = ConfigDict(
        extra='forbid',
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Subject19 (**data: Any)
Expand source code
class Subject19(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['resource'] = 'resource'
    resource_type: Annotated[
        Literal['https://adcontextprotocol.org/claims/subjects/rights-grant'],
        Field(
            description='Open, absolute URI naming the subject vocabulary, such as https://adcontextprotocol.org/claims/subjects/signal. AdCP does not maintain an exhaustive enum.'
        ),
    ] = 'https://adcontextprotocol.org/claims/subjects/rights-grant'
    namespace: Annotated[
        AnyUrl,
        Field(
            description='Absolute URI identifying the namespace in which id is unique. This may be an AdCP agent endpoint, a catalog origin, or a domain-specific namespace URI.'
        ),
    ]
    id: Annotated[
        str,
        Field(
            description='Stable identifier for the subject within namespace. It MUST NOT be compared without resource_type and namespace.',
            max_length=1024,
            min_length=1,
        ),
    ]
    content_digest: Annotated[
        str,
        Field(
            description='Optional SHA-256 pin for the exact content or immutable snapshot identified by this resource subject. This is part of the complete typed subject identity and is distinct from AttestationReference.content_digest, which pins credential bytes.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    ext: ext_1.ExtensionObject | 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 content_digest : str
var ext : ExtensionObject | None
var id : str
var model_config
var namespace : pydantic.networks.AnyUrl
var resource_type : Literal['https://adcontextprotocol.org/claims/subjects/rights-grant']
var type : Literal['resource']

Inherited members

class Subject2 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class Subject2(RootModel[Subject25 | Subject26 | Subject27]):
    root: Annotated[
        Subject25 | Subject26 | Subject27,
        Field(
            description='Typed identity of the entity or object an attestation credential is about. Brand and agent subjects reuse canonical AdCP identities. Other resources use an open, URI-namespaced resource_type plus an identifier whose namespace is explicit. Evaluators MUST compare the resolved credential subject to this complete typed identity, not to id alone.',
            discriminator='type',
            examples=[
                {
                    'type': 'brand',
                    'brand': {'domain': 'nova-brands.example', 'brand_id': 'nova_motors'},
                },
                {
                    'type': 'resource',
                    'resource_type': 'https://adcontextprotocol.org/claims/subjects/signal',
                    'namespace': 'https://signals.meridian.example/adcp',
                    'id': 'signal_urban_commuters',
                },
            ],
            title='AttestationAgentSubject',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[Subject25, Subject26, Subject27]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Subject25 | Subject26 | Subject27
class Subject20 (**data: Any)
Expand source code
class Subject20(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['brand'] = 'brand'
    resource_type: Literal['https://adcontextprotocol.org/claims/subjects/rights-grant'] = 'https://adcontextprotocol.org/claims/subjects/rights-grant'
    brand: brand_ref.BrandReference
    ext: ext_1.ExtensionObject | 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 brand : BrandReference
var ext : ExtensionObject | None
var model_config
var resource_type : Literal['https://adcontextprotocol.org/claims/subjects/rights-grant']
var type : Literal['brand']

Inherited members

class Subject21 (**data: Any)
Expand source code
class Subject21(Subject11):
    pass

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 model_config

Inherited members

class Subject22 (**data: Any)
Expand source code
class Subject22(Subject12):
    pass

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 model_config

Inherited members

class Subject23 (**data: Any)
Expand source code
class Subject23(Subject13):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Subject24 (**data: Any)
Expand source code
class Subject24(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['resource'] = 'resource'
    resource_type: Literal['https://adcontextprotocol.org/claims/subjects/audience-evidence'] = 'https://adcontextprotocol.org/claims/subjects/audience-evidence'
    content_digest: Annotated[str, Field(pattern='^sha256:[a-f0-9]{64}$')]
    agent_url: Annotated[
        AnyUrl, Field(description='Canonical HTTPS endpoint of the agent the claim concerns.')
    ]
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var agent_url : pydantic.networks.AnyUrl
var content_digest : str
var ext : ExtensionObject | None
var model_config
var resource_type : Literal['https://adcontextprotocol.org/claims/subjects/audience-evidence']
var type : Literal['resource']

Inherited members

class Subject25 (**data: Any)
Expand source code
class Subject25(Subject21):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[
        AnyUrl, Field(description='Canonical HTTPS endpoint of the agent the claim concerns.')
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var model_config

Inherited members

class Subject26 (**data: Any)
Expand source code
class Subject26(Subject22):
    model_config = ConfigDict(
        extra='forbid',
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Subject27 (**data: Any)
Expand source code
class Subject27(Subject24):
    model_config = ConfigDict(
        extra='forbid',
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Subject29 (**data: Any)
Expand source code
class Subject29(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['resource'] = 'resource'
    resource_type: Annotated[
        Literal['https://adcontextprotocol.org/claims/subjects/rights-grant'],
        Field(
            description='Open, absolute URI naming the subject vocabulary, such as https://adcontextprotocol.org/claims/subjects/signal. AdCP does not maintain an exhaustive enum.'
        ),
    ] = 'https://adcontextprotocol.org/claims/subjects/rights-grant'
    namespace: Annotated[
        AnyUrl,
        Field(
            description='Absolute URI identifying the namespace in which id is unique. This may be an AdCP agent endpoint, a catalog origin, or a domain-specific namespace URI.'
        ),
    ]
    id: Annotated[
        str,
        Field(
            description='Stable identifier for the subject within namespace. It MUST NOT be compared without resource_type and namespace.',
            max_length=1024,
            min_length=1,
        ),
    ]
    content_digest: Annotated[
        str,
        Field(
            description='Optional SHA-256 pin for the exact content or immutable snapshot identified by this resource subject. This is part of the complete typed subject identity and is distinct from AttestationReference.content_digest, which pins credential bytes.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    ext: ext_1.ExtensionObject | 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 content_digest : str
var ext : ExtensionObject | None
var id : str
var model_config
var namespace : pydantic.networks.AnyUrl
var resource_type : Literal['https://adcontextprotocol.org/claims/subjects/rights-grant']
var type : Literal['resource']

Inherited members

class Subject3 (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class Subject3(RootModel[Subject35 | Subject36 | Subject37]):
    root: Annotated[
        Subject35 | Subject36 | Subject37,
        Field(
            description='Typed identity of the entity or object an attestation credential is about. Brand and agent subjects reuse canonical AdCP identities. Other resources use an open, URI-namespaced resource_type plus an identifier whose namespace is explicit. Evaluators MUST compare the resolved credential subject to this complete typed identity, not to id alone.',
            discriminator='type',
            examples=[
                {
                    'type': 'brand',
                    'brand': {'domain': 'nova-brands.example', 'brand_id': 'nova_motors'},
                },
                {
                    'type': 'resource',
                    'resource_type': 'https://adcontextprotocol.org/claims/subjects/signal',
                    'namespace': 'https://signals.meridian.example/adcp',
                    'id': 'signal_urban_commuters',
                },
            ],
            title='AttestationResourceSubject',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[Subject35, Subject36, Subject37]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Subject35 | Subject36 | Subject37
class Subject31 (**data: Any)
Expand source code
class Subject31(Subject11):
    pass

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 model_config

Inherited members

class Subject32 (**data: Any)
Expand source code
class Subject32(Subject12):
    pass

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 model_config

Inherited members

class Subject33 (**data: Any)
Expand source code
class Subject33(Subject13):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Subject34 (**data: Any)
Expand source code
class Subject34(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Literal['resource'] = 'resource'
    resource_type: Literal['https://adcontextprotocol.org/claims/subjects/audience-evidence'] = 'https://adcontextprotocol.org/claims/subjects/audience-evidence'
    content_digest: Annotated[str, Field(pattern='^sha256:[a-f0-9]{64}$')]
    namespace: Annotated[
        AnyUrl,
        Field(
            description='Absolute URI identifying the namespace in which id is unique. This may be an AdCP agent endpoint, a catalog origin, or a domain-specific namespace URI.'
        ),
    ]
    id: Annotated[
        str,
        Field(
            description='Stable identifier for the subject within namespace. It MUST NOT be compared without resource_type and namespace.',
            max_length=1024,
            min_length=1,
        ),
    ]
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var content_digest : str
var ext : ExtensionObject | None
var id : str
var model_config
var namespace : pydantic.networks.AnyUrl
var resource_type : Literal['https://adcontextprotocol.org/claims/subjects/audience-evidence']
var type : Literal['resource']

Inherited members

class Subject35 (**data: Any)
Expand source code
class Subject35(Subject31):
    model_config = ConfigDict(
        extra='forbid',
    )
    resource_type: Annotated[
        AnyUrl,
        Field(
            description='Open, absolute URI naming the subject vocabulary, such as https://adcontextprotocol.org/claims/subjects/signal. AdCP does not maintain an exhaustive enum.'
        ),
    ]
    namespace: Annotated[
        AnyUrl,
        Field(
            description='Absolute URI identifying the namespace in which id is unique. This may be an AdCP agent endpoint, a catalog origin, or a domain-specific namespace URI.'
        ),
    ]
    id: Annotated[
        str,
        Field(
            description='Stable identifier for the subject within namespace. It MUST NOT be compared without resource_type and namespace.',
            max_length=1024,
            min_length=1,
        ),
    ]
    content_digest: Annotated[
        str | None,
        Field(
            description='Optional SHA-256 pin for the exact content or immutable snapshot identified by this resource subject. This is part of the complete typed subject identity and is distinct from AttestationReference.content_digest, which pins credential bytes.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = 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 content_digest : str | None
var id : str
var model_config
var namespace : pydantic.networks.AnyUrl
var resource_type : pydantic.networks.AnyUrl

Inherited members

class Subject36 (**data: Any)
Expand source code
class Subject36(Subject32):
    model_config = ConfigDict(
        extra='forbid',
    )
    resource_type: Annotated[
        AnyUrl,
        Field(
            description='Open, absolute URI naming the subject vocabulary, such as https://adcontextprotocol.org/claims/subjects/signal. AdCP does not maintain an exhaustive enum.'
        ),
    ]
    namespace: Annotated[
        AnyUrl,
        Field(
            description='Absolute URI identifying the namespace in which id is unique. This may be an AdCP agent endpoint, a catalog origin, or a domain-specific namespace URI.'
        ),
    ]
    id: Annotated[
        str,
        Field(
            description='Stable identifier for the subject within namespace. It MUST NOT be compared without resource_type and namespace.',
            max_length=1024,
            min_length=1,
        ),
    ]
    content_digest: Annotated[
        str | None,
        Field(
            description='Optional SHA-256 pin for the exact content or immutable snapshot identified by this resource subject. This is part of the complete typed subject identity and is distinct from AttestationReference.content_digest, which pins credential bytes.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = 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 content_digest : str | None
var id : str
var model_config
var namespace : pydantic.networks.AnyUrl
var resource_type : pydantic.networks.AnyUrl

Inherited members

class Subject37 (**data: Any)
Expand source code
class Subject37(Subject34):
    model_config = ConfigDict(
        extra='forbid',
    )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Summary (**data: Any)
Expand source code
class Summary(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    matched: Annotated[
        SchemaInt,
        Field(
            description='Resolved entries that matched at least one property in this product.', ge=0
        ),
    ]
    unmatched: Annotated[
        SchemaInt,
        Field(description='Resolved entries that did not match a property in this product.', ge=0),
    ]

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 matched : int
var model_config
var unmatched : int

Inherited members

class Summary2 (**data: Any)
Expand source code
class Summary2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    matched: Annotated[
        SchemaInt,
        Field(
            description='Resolved entries that matched at least one collection in this product.',
            ge=0,
        ),
    ]
    unmatched: Annotated[
        SchemaInt,
        Field(
            description='Resolved entries that did not match a collection in this product.', ge=0
        ),
    ]

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 matched : int
var model_config
var unmatched : int

Inherited members

class Supported (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class Supported(RootModel[Literal[True]]):
    root: Literal[True]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Literal[True]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Literal[True]
class SupportedDeliveryMethod (*args, **kwds)
Expand source code
class SupportedDeliveryMethod(StrEnum):
    credential_uri = 'credential_uri'
    issuer_credential_id = 'issuer_credential_id'
    embedded = 'embedded'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var credential_uri
var embedded
var issuer_credential_id
class SupportedMetric (*args, **kwds)
Expand source code
class SupportedMetric(StrEnum):
    clicks = 'clicks'
    views = 'views'
    completed_views = 'completed_views'
    viewed_seconds = 'viewed_seconds'
    viewable_rate = 'viewable_rate'
    attention_seconds = 'attention_seconds'
    attention_score = 'attention_score'
    engagements = 'engagements'
    follows = 'follows'
    saves = 'saves'
    profile_visits = 'profile_visits'
    reach = 'reach'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var attention_score
var attention_seconds
var clicks
var completed_views
var engagements
var follows
var profile_visits
var reach
var saves
var viewable_rate
var viewed_seconds
var views
class SupportedTarget5 (*args, **kwds)
Expand source code
class SupportedTarget5(StrEnum):
    cost_per = 'cost_per'
    per_ad_spend = 'per_ad_spend'
    maximize_value = 'maximize_value'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var cost_per
var maximize_value
var per_ad_spend
class SupportedTimezone (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class SupportedTimezone(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class SupportedVersion (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class SupportedVersion(ScalarStr):
    __slots__ = ()
    _constraints = {'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class SupportedViewDuration (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class SupportedViewDuration(ScalarFloat):
    __slots__ = ()
    _constraints = {'gt': 0.0}

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._scalar.ScalarFloat
  • adcp.types._scalar._ScalarRoot
  • builtins.float
class SyncCatalogsInputRequired (**data: Any)
Expand source code
class SyncCatalogsInputRequired(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    reason: Annotated[
        Reason | None,
        Field(
            description='Reason code indicating why buyer input is needed. APPROVAL_REQUIRED: platform requires explicit approval before activating the catalog. FEED_VALIDATION: feed URL returned unexpected format or schema errors. ITEM_REVIEW: platform flagged items for manual review. FEED_ACCESS: platform cannot access the feed URL (authentication, CORS, etc.).'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var reason : Reason | None

Inherited members

class SyncCatalogsSubmitted (**data: Any)
Expand source code
class SyncCatalogsSubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose catalogs array is issued in-line. See task-status.json for the full task-status enum.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='Task handle the buyer uses with get_task_status (or the legacy AdCP tasks/get alias), and that the seller references on push-notification callbacks. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A Task id.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description="Optional human-readable explanation of why the task is submitted — e.g., 'Catalog ingestion queued; typical turnaround 5–15 minutes.' Plain text only. Buyers MUST treat this as untrusted seller input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile seller may inject prompt-injection payloads aimed at the buyer's agent.",
            max_length=2000,
        ),
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories, governance observations). Terminal failures belong in the error branch, not here.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class SyncCatalogsWorking (**data: Any)
Expand source code
class SyncCatalogsWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0)
    ] = None
    current_step: Annotated[
        str | None,
        Field(
            description="Current step or phase of the operation (e.g., 'Fetching product feed', 'Validating items', 'Platform review')"
        ),
    ] = None
    total_steps: Annotated[
        SchemaInt | None, Field(description='Total number of steps in the operation', ge=1)
    ] = None
    step_number: Annotated[SchemaInt | None, Field(description='Current step number', ge=1)] = None
    catalogs_processed: Annotated[
        SchemaInt | None, Field(description='Number of catalogs processed so far', ge=0)
    ] = None
    catalogs_total: Annotated[
        SchemaInt | None, Field(description='Total number of catalogs to process', ge=0)
    ] = None
    items_processed: Annotated[
        SchemaInt | None,
        Field(description='Total number of catalog items processed across all catalogs', ge=0),
    ] = None
    items_total: Annotated[
        SchemaInt | None,
        Field(description='Total number of catalog items to process across all catalogs', ge=0),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 catalogs_processed : int | None
var catalogs_total : int | None
var context : ContextObject | None
var current_step : str | None
var ext : ExtensionObject | None
var items_processed : int | None
var items_total : int | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class SyncCreativesInputRequired (**data: Any)
Expand source code
class SyncCreativesInputRequired(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    reason: Annotated[
        Reason | None, Field(description='Reason code indicating why buyer input is needed')
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var reason : Reason | None

Inherited members

class SyncCreativesSubmitted (**data: Any)
Expand source code
class SyncCreativesSubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose creatives array carries per-item approval state via CreativeStatus. See task-status.json for the full task-status enum.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='Task handle the buyer uses with get_task_status (or the legacy AdCP tasks/get alias), and that the seller references on push-notification callbacks. The creatives array is issued on the completion artifact, not here. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A Task id.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description="Optional human-readable explanation of why the task is submitted — e.g., 'Batch ingestion queued; typical turnaround 15-30 minutes.' Plain text only. Buyers MUST treat this as untrusted seller input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile seller may inject prompt-injection payloads aimed at the buyer's agent.",
            max_length=2000,
        ),
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories, governance observations). Terminal failures belong in the error branch, not here.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class SyncCreativesWorking (**data: Any)
Expand source code
class SyncCreativesWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0)
    ] = None
    current_step: Annotated[
        str | None, Field(description='Current step or phase of the operation')
    ] = None
    total_steps: Annotated[
        SchemaInt | None, Field(description='Total number of steps in the operation', ge=1)
    ] = None
    step_number: Annotated[SchemaInt | None, Field(description='Current step number', ge=1)] = None
    creatives_processed: Annotated[
        SchemaInt | None, Field(description='Number of creatives processed so far', ge=0)
    ] = None
    creatives_total: Annotated[
        SchemaInt | None, Field(description='Total number of creatives to process', ge=0)
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var creatives_processed : int | None
var creatives_total : int | None
var current_step : str | None
var ext : ExtensionObject | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class System1 (*args, **kwds)
Expand source code
class System1(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'
    outward_1 = 'outward'
    full_1 = 'full'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var de_plz
var fr_code_postal
var fsa
var full
var full_1
var gb_full
var gb_outward
var outward
var outward_1
var pin
var plz
var postal_code
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class System11 (*args, **kwds)
Expand source code
class System11(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'
    outward_1 = 'outward'
    full_1 = 'full'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var de_plz
var fr_code_postal
var fsa
var full
var full_1
var gb_full
var gb_outward
var outward
var outward_1
var pin
var plz
var postal_code
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class System12 (*args, **kwds)
Expand source code
class System12(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'
    fsa_1 = 'fsa'
    full_1 = 'full'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var de_plz
var fr_code_postal
var fsa
var fsa_1
var full
var full_1
var gb_full
var gb_outward
var outward
var pin
var plz
var postal_code
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class System13 (*args, **kwds)
Expand source code
class System13(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var de_plz
var fr_code_postal
var fsa
var full
var gb_full
var gb_outward
var outward
var pin
var plz
var postal_code
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class System19 (*args, **kwds)
Expand source code
class System19(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'
    postal_code_1 = 'postal_code'
    custom_1 = 'custom'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var custom_1
var de_plz
var fr_code_postal
var fsa
var full
var gb_full
var gb_outward
var outward
var pin
var plz
var postal_code
var postal_code_1
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class System2 (*args, **kwds)
Expand source code
class System2(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'
    fsa_1 = 'fsa'
    full_1 = 'full'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var de_plz
var fr_code_postal
var fsa
var fsa_1
var full
var full_1
var gb_full
var gb_outward
var outward
var pin
var plz
var postal_code
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class System3 (*args, **kwds)
Expand source code
class System3(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var de_plz
var fr_code_postal
var fsa
var full
var gb_full
var gb_outward
var outward
var pin
var plz
var postal_code
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class System9 (*args, **kwds)
Expand source code
class System9(StrEnum):
    postal_code = 'postal_code'
    zip = 'zip'
    zip_plus_four = 'zip_plus_four'
    outward = 'outward'
    full = 'full'
    fsa = 'fsa'
    plz = 'plz'
    code_postal = 'code_postal'
    postcode = 'postcode'
    cep = 'cep'
    pin = 'pin'
    custom = 'custom'
    us_zip = 'us_zip'
    us_zip_plus_four = 'us_zip_plus_four'
    gb_outward = 'gb_outward'
    gb_full = 'gb_full'
    ca_fsa = 'ca_fsa'
    ca_full = 'ca_full'
    de_plz = 'de_plz'
    fr_code_postal = 'fr_code_postal'
    au_postcode = 'au_postcode'
    ch_plz = 'ch_plz'
    at_plz = 'at_plz'
    postal_code_1 = 'postal_code'
    custom_1 = 'custom'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var at_plz
var au_postcode
var ca_fsa
var ca_full
var cep
var ch_plz
var code_postal
var custom
var custom_1
var de_plz
var fr_code_postal
var fsa
var full
var gb_full
var gb_outward
var outward
var pin
var plz
var postal_code
var postal_code_1
var postcode
var us_zip
var us_zip_plus_four
var zip
var zip_plus_four
class Tag (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class Tag(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^[a-z0-9_-]+$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class Talent (**data: Any)
Expand source code
class Talent(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    role: Annotated[
        talent_role.TalentRole,
        Field(description='Role of this person on the collection or installment'),
    ]
    name: Annotated[str, Field(description="Person's name as credited on the collection")]
    brand_url: Annotated[
        AnyUrl | None,
        Field(
            description="URL to this person's brand.json entry. Enables buyer agents to evaluate the talent's brand identity and associations."
        ),
    ] = 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 brand_url : pydantic.networks.AnyUrl | None
var model_config
var name : str
var role : TalentRole

Inherited members

class Target1 (*args, **kwds)
Expand source code
class Target1(StrEnum):
    linear = 'linear'
    companion = 'companion'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var companion
var linear
class Target10 (**data: Any)
Expand source code
class Target10(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['maximize_value'] = 'maximize_value'

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var kind : Literal['maximize_value']
var model_config

Inherited members

class Target11 (**data: Any)
Expand source code
class Target11(Target):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Target14 (**data: Any)
Expand source code
class Target14(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['threshold_rate'] = 'threshold_rate'
    value: Annotated[
        StrictFloat,
        Field(
            description='Minimum per-impression value. Units depend on the metric: proportion (clicks, views, completed_views, viewable_rate), seconds (viewed_seconds, attention_seconds), or score (attention_score).',
            gt=0.0,
        ),
    ]

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 kind : Literal['threshold_rate']
var model_config
var value : float

Inherited members

class Target15 (**data: Any)
Expand source code
class Target15(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['cost_per'] = 'cost_per'
    value: Annotated[
        StrictFloat, Field(description='Target cost per event in the buy currency', gt=0.0)
    ]

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 kind : Literal['cost_per']
var model_config
var value : float

Inherited members

class Target16 (**data: Any)
Expand source code
class Target16(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['per_ad_spend'] = 'per_ad_spend'
    value: Annotated[
        StrictFloat,
        Field(description='Target return ratio (e.g., 4.0 means $4 of value per $1 spent)', gt=0.0),
    ]

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 kind : Literal['per_ad_spend']
var model_config
var value : float

Inherited members

class Target17 (**data: Any)
Expand source code
class Target17(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['maximize_value'] = 'maximize_value'

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var kind : Literal['maximize_value']
var model_config

Inherited members

class Target18 (**data: Any)
Expand source code
class Target18(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['cost_per'] = 'cost_per'
    value: Annotated[
        StrictFloat,
        Field(
            description='Target cost per metric unit in the buy currency. Units of the metric are vendor-defined.',
            gt=0.0,
        ),
    ]

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 kind : Literal['cost_per']
var model_config
var value : float

Inherited members

class Target19 (**data: Any)
Expand source code
class Target19(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['threshold_rate'] = 'threshold_rate'
    value: Annotated[
        StrictFloat,
        Field(
            description='Minimum per-impression value. Units of the metric are vendor-defined.',
            gt=0.0,
        ),
    ]

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 kind : Literal['threshold_rate']
var model_config
var value : float

Inherited members

class Target3 (**data: Any)
Expand source code
class Target3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['threshold_rate'] = 'threshold_rate'
    value: Annotated[
        StrictFloat,
        Field(
            description='Minimum per-impression value. Units depend on the metric: proportion (clicks, views, completed_views, viewable_rate), seconds (viewed_seconds, attention_seconds), or score (attention_score).',
            gt=0.0,
        ),
    ]

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 kind : Literal['threshold_rate']
var model_config
var value : float

Inherited members

class Target4 (**data: Any)
Expand source code
class Target4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['cost_per'] = 'cost_per'
    value: Annotated[
        StrictFloat, Field(description='Target cost per event in the buy currency', gt=0.0)
    ]

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 kind : Literal['cost_per']
var model_config
var value : float

Inherited members

class Target5 (**data: Any)
Expand source code
class Target5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['per_ad_spend'] = 'per_ad_spend'
    value: Annotated[
        StrictFloat,
        Field(description='Target return ratio (e.g., 4.0 means $4 of value per $1 spent)', gt=0.0),
    ]

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 kind : Literal['per_ad_spend']
var model_config
var value : float

Inherited members

class Target6 (**data: Any)
Expand source code
class Target6(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['maximize_value'] = 'maximize_value'

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var kind : Literal['maximize_value']
var model_config

Inherited members

class Target7 (**data: Any)
Expand source code
class Target7(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['cost_per'] = 'cost_per'
    value: Annotated[
        StrictFloat,
        Field(
            description='Target cost per metric unit in the buy currency. Units of the metric are vendor-defined.',
            gt=0.0,
        ),
    ]

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 kind : Literal['cost_per']
var model_config
var value : float

Inherited members

class Target8 (**data: Any)
Expand source code
class Target8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Literal['threshold_rate'] = 'threshold_rate'
    value: Annotated[
        StrictFloat,
        Field(
            description='Minimum per-impression value. Units of the metric are vendor-defined.',
            gt=0.0,
        ),
    ]

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 kind : Literal['threshold_rate']
var model_config
var value : float

Inherited members

class TargetVariant (**data: Any)
Expand source code
class TargetVariant(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    locale_variant_id: Annotated[
        str,
        Field(
            description='Buyer-assigned stable identity for this target locale variant. The same value round-trips through sync_creatives, list_creatives, and localized delivery reporting.',
            max_length=255,
            min_length=1,
        ),
    ]
    locale: locale_tag.LanguageTag
    assets: Annotated[
        dict[
            Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')],
            localized_creative_asset.LocalizedCreativeAsset | Assets,
        ],
        Field(
            description='Materialized locale-specific asset overrides keyed by the same slot IDs as the source creative. Missing slots inherit source assets.'
        ),
    ]

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 assets : dict[str, LocalizedCreativeAsset | Assets]
var locale : LanguageTag
var locale_variant_id : str
var model_config

Inherited members

class TargetingModification1 (**data: Any)
Expand source code
class TargetingModification1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    operation: Literal['replace'] = 'replace'
    path: Annotated[
        str,
        Field(
            description='RFC 6901 JSON Pointer to one complete targeting value relative to targeting_overlay, for example /demographics/age. Array indexes are forbidden by protocol semantics even if syntactically valid JSON Pointer; target a stable whole dimension instead.',
            pattern='^(?:/(?:[^~/]|~[01])*)+$',
        ),
    ]
    applied: Annotated[
        Any,
        Field(
            description='Complete replacement value. It MUST validate against targeting.json at path; the seller then validates the complete effective overlay. This operation may narrow or broaden only as an explicit buyer-visible proposal.'
        ),
    ]
    reason: Annotated[str, Field(min_length=1)]
    ext: ext_1.ExtensionObject | 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 applied : Any
var ext : ExtensionObject | None
var model_config
var operation : Literal['replace']
var path : str
var reason : str

Inherited members

class TargetingModification2 (**data: Any)
Expand source code
class TargetingModification2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    operation: Literal['remove_values'] = 'remove_values'
    path: Annotated[
        Path,
        Field(
            description='Supported targeting field with string-set semantics. Postal-area paths identify their group with selector; direct top-level sets omit selector.'
        ),
    ]
    selector: Annotated[
        Selector | None,
        Field(
            description='Stable identity of exactly one postal-area group in the requested array. Required only for postal-area paths. Zero or multiple matches make the modification invalid.'
        ),
    ] = None
    values: Annotated[
        list[str],
        Field(
            description='Values removed from the requested set. Values absent from that set are invalid rather than no-ops.',
            min_length=1,
        ),
    ]
    reason: Annotated[str, Field(min_length=1)]
    ext: ext_1.ExtensionObject | 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 ext : ExtensionObject | None
var model_config
var operation : Literal['remove_values']
var path : Path
var reason : str
var selector : Selector | None
var values : list[str]

Inherited members

class TargetingOverlay (**data: Any)
Expand source code
class TargetingOverlay(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    geo_countries: Annotated[
        list[GeoCountry] | None,
        Field(
            description="Restrict delivery to specific countries. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').",
            min_length=1,
        ),
    ] = None
    geo_countries_exclude: Annotated[
        Sequence[GeoCountriesExcludeItem] | None,
        Field(
            description="Exclude specific countries from delivery. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').",
            min_length=1,
        ),
    ] = None
    geo_regions: Annotated[
        list[GeoRegion] | None,
        Field(
            description='Restrict delivery to exact canonical ISO 3166-2 subdivisions (states, provinces, regions, departments, or other subdivision categories). Unknown identifiers are invalid. At create or update, sellers MUST reject unsupported identifiers and MUST NOT silently widen, drop, or partially apply the list. During get_products, a seller may instead return a sparse, buyer-reviewable targeting_resolution modification for a valid but unsupported requested outcome. Exact internal translation preserves accepted identifiers in package readback.',
            min_length=1,
        ),
    ] = None
    geo_regions_exclude: Annotated[
        Sequence[GeoRegionsExcludeItem] | None,
        Field(
            description='Exclude exact canonical ISO 3166-2 subdivisions. Support is independent from geo_regions inclusion support. Unknown identifiers and values also present in geo_regions are invalid. At create or update, sellers MUST reject unsupported identifiers and partial application; during get_products, a seller may instead return a sparse, buyer-reviewable targeting_resolution modification for a valid but unsupported requested outcome.',
            min_length=1,
        ),
    ] = None
    geo_metros: Annotated[
        list[geo_metro.GeoMetro] | None,
        Field(
            description='Restrict delivery to specific metro areas. Each entry specifies the classification system and target values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
            title='Targeting Geo Metros',
        ),
    ] = None
    geo_metros_exclude: Annotated[
        Sequence[GeoMetrosExcludeItem] | None,
        Field(
            description='Exclude specific metro areas from delivery. Each entry specifies the classification system and excluded values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_postal_areas: Annotated[
        list[postal_area.PostalArea] | None,
        Field(
            description='Restrict delivery to specific postal areas. Prefer the native country + postal system form. The deprecated legacy country-fused postal-system tokens remain accepted for compatibility. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_postal_areas_exclude: Annotated[
        Sequence[postal_area.PostalArea] | None,
        Field(
            description='Exclude specific postal areas from delivery. Prefer the native country + postal system form. The deprecated legacy country-fused postal-system tokens remain accepted for compatibility. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_places: Annotated[
        list[geo_place_area.GeographicPlaceArea] | None,
        Field(
            description='Restrict delivery to catalog-backed named places. Values MUST be stable identifiers in the declared system, not display names. Sellers must declare supported systems, countries, and place types in get_adcp_capabilities and reject unsupported entries rather than silently dropping them.',
            min_length=1,
        ),
    ] = None
    geo_places_exclude: Annotated[
        list[geo_place_area.GeographicPlaceArea] | None,
        Field(
            description='Exclude catalog-backed named places. Uses the same identifier-based shape as geo_places. Sellers MUST reject overlap with geo_places for the same country, system, place_type, and value.',
            min_length=1,
        ),
    ] = None
    daypart_targets: Annotated[
        list[daypart_target.DaypartTarget] | None,
        Field(
            description='Restrict delivery to specific time windows. Each entry specifies days of week, an hour range, and an optional timezone that defaults to inventory_local. A concrete IANA zone uses one shared civil-time clock, while inventory_local evaluates each inventory unit in its seller-assigned local timezone. Entries are independent and MAY use different clocks.',
            min_length=1,
        ),
    ] = None
    axe_include_segment: Annotated[
        str | None,
        Field(
            deprecated=True,
            description='Deprecated: Use TMP provider fields instead. AXE segment ID to include for targeting.',
        ),
    ] = None
    axe_exclude_segment: Annotated[
        str | None,
        Field(
            deprecated=True,
            description='Deprecated: Use TMP provider fields instead. AXE segment ID to exclude from targeting.',
        ),
    ] = None
    audience_include: Annotated[
        list[str] | None,
        Field(
            description='Restrict delivery to members of these first-party CRM audiences. Only users present in the uploaded lists are eligible. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Not for lookalike expansion — express that intent in the campaign brief. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    audience_exclude: Annotated[
        list[str] | None,
        Field(
            description='Suppress delivery to members of these first-party CRM audiences. Matched users are excluded regardless of other targeting. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    signal_targeting_groups: Annotated[
        package_signal_targeting_groups.PackageSignalTargetingGroups | None,
        Field(
            description="Basic Boolean grouping for seller-offered signals. v1 supports a required top-level operator 'all' and child groups with operator 'any' for include groups or 'none' for exclusion groups. Example semantics: group 1 any(A, B) plus group 2 none(C, D) means (A OR B) AND NOT (C OR D). Signal entries reference named signal definitions with signal_ref scope 'product' for product-local signal options or scope 'data_provider' for external signals published in adagents.json signals[]. For simple include-only targeting, send one child group with operator 'any'. Sellers SHOULD reject entries that are not available for the product through inline signal_targeting_options or get_signals, are not active for the account, or exceed the product's signal_targeting_allowed/signal_targeting_rules/product terms. Signal targeting limits are product-scoped, not declared in get_adcp_capabilities, because products may be backed by different ad servers. Sellers MUST echo applied signal_targeting_groups on the resulting package state, including fixed/default selections. Sellers MAY return REQUOTE_REQUIRED when a targeting mutation changes commercial terms.",
            title='Targeting Signal Groups',
        ),
    ] = None
    signal_targeting: Annotated[
        list[signal_targeting_1.SignalTargeting] | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_targeting_groups for package-level signal targeting. Legacy flat signal_targeting remains accepted during the SignalRef migration window but cannot express grouped include/exclude composition or product-scoped pricing.',
            min_length=1,
        ),
    ] = None
    demographics: Annotated[
        demographic_targeting_intent.DemographicTargetingIntent | None,
        Field(
            description='Canonical demographic audience targeting intent with optional constraints on how age may be determined. This is distinct from age_restriction: demographics selects an audience, while age_restriction expresses a legal eligibility or verification floor. Fresh create/update targeting MUST compile exactly or be rejected. During get_products, a seller may offer a different configured predicate only through sparse targeting_resolution modifications on a distinguishable product_id; selecting that product accepts the alternative. Sellers never silently broaden, narrow, default, drop, or substitute the basis.'
        ),
    ] = None
    frequency_cap: Annotated[
        frequency_cap_1.FrequencyCap | None, Field(title='Targeting Frequency Cap')
    ] = None
    property_list: Annotated[
        property_list_ref.PropertyListReference | None,
        Field(
            description="Reference to a property list for targeting specific properties within this product. The package runs on the intersection of the product's publisher_properties and this list. Sellers SHOULD return a validation error if the product has property_targeting_allowed: false.",
            title='Targeting Property List',
        ),
    ] = None
    property_list_exclude: Annotated[
        property_list_ref.PropertyListReference | None,
        Field(
            description="Reference to a property list whose properties must not carry the buyer's ads. Matched properties are removed from delivery. Use for brand-safety do-not-run lists (apps, sites). Exclude wins on overlap with property_list, and applies regardless of the product's property_targeting_allowed flag. Seller must declare support in get_adcp_capabilities."
        ),
    ] = None
    collection_list: Annotated[
        collection_list_ref.CollectionListReference | None,
        Field(
            description='Reference to a collection list for including specific collections (programs, publications, channels) within this product. The package runs on the intersection of matched collections and this list. Use for inclusion-based collection targeting. Seller must declare support in get_adcp_capabilities.',
            title='Targeting Collection List',
        ),
    ] = None
    collection_list_exclude: Annotated[
        collection_list_ref.CollectionListReference | None,
        Field(
            description="Reference to a collection list for excluding specific collections (programs, publications, channels) from this product. Matched collections must not carry the buyer's ads. Use for brand safety do-not-air lists. Seller must declare support in get_adcp_capabilities."
        ),
    ] = None
    placement_selection: Annotated[
        placement_selection_1.PlacementSelection | None,
        Field(
            description='Purchased placement selection within the product. This constrains package inventory; it is distinct from creative_assignments[].placement_refs, which only route individual creatives within the purchased set. On create, mode selected supplies the complete selected set and mode default uses the product default. In request-side Targeting Input, a non-null value replaces this dimension, omission preserves or inherits it, and null clears it when the product permits that broader inventory set.'
        ),
    ] = None
    collection_selection: Annotated[
        collection_selection_1.CollectionSelection | None,
        Field(
            description="Purchased collection selection within the product. On create, mode selected supplies the complete selected set and mode default uses the product's full bundle. On package readback this is the committed selection sellers MUST echo as concrete selectors, materializing any collection_list composition; collection_list fields remain the buyer-managed list mechanism. In request-side Targeting Input, a non-null value replaces this dimension, omission preserves or inherits it, and null clears it when the product permits that broader inventory set.",
            title='Targeting Collection Selection',
        ),
    ] = None
    age_restriction: Annotated[
        AgeRestriction | None,
        Field(
            description='Age restriction for compliance. Use for legal requirements (alcohol, gambling), not audience targeting.'
        ),
    ] = None
    device_platform: Annotated[
        list[device_platform_1.DevicePlatform] | None,
        Field(
            description='Restrict to specific platforms. Use for technical compatibility (app only works on iOS). Values from Sec-CH-UA-Platform standard, extended for CTV.',
            min_length=1,
        ),
    ] = None
    device_platform_exclude: Annotated[
        list[device_platform_1.DevicePlatform] | None,
        Field(
            description='Exclude specific operating-system platforms from delivery. When a platform appears in both device_platform and device_platform_exclude, exclusion wins. Sellers MUST reject a request they cannot enforce rather than silently dropping the exclusion.',
            min_length=1,
        ),
    ] = None
    device_type: Annotated[
        list[device_type_1.DeviceType] | None,
        Field(
            description='Restrict to specific device form factors. Use for campaigns targeting hardware categories rather than operating systems (e.g., mobile-only promotions, CTV campaigns).',
            min_length=1,
        ),
    ] = None
    device_type_exclude: Annotated[
        list[device_type_1.DeviceType] | None,
        Field(
            description='Exclude specific device form factors from delivery (e.g., exclude CTV for app-install campaigns).',
            min_length=1,
        ),
    ] = None
    browser: Annotated[
        list[browser_family.BrowserFamily] | None,
        Field(
            description='Restrict delivery to specific canonical browser families in the impression delivery and rendering environment, not the post-click landing-page browser. Values MUST NOT be inferred solely from operating system, device, web/mobile-web inventory, or placement. Values in this array use OR semantics. When browser is supplied, families not listed are ineligible: other includes a seller-recognized family that is not explicitly enumerated, while unknown includes a browser the seller cannot classify into a recognized family. When the same family appears in browser and browser_exclude, exclusion wins. Browser and device constraints intersect; a seller that cannot enforce the exact combination MUST exclude or explicitly reconfigure the product during discovery and MUST reject it at create or update rather than silently widening delivery. Browser versions and seller-native IDs are intentionally unsupported.',
            min_length=1,
        ),
    ] = None
    browser_exclude: Annotated[
        list[browser_family.BrowserFamily] | None,
        Field(
            description='Exclude specific canonical browser families from delivery. other excludes seller-recognized families that are not explicitly enumerated; unknown excludes browsers the seller cannot classify into a recognized family. When the same family appears in browser and browser_exclude, exclusion wins. Sellers MUST reject a request they cannot enforce rather than silently dropping the exclusion.',
            min_length=1,
        ),
    ] = None
    store_catchments: Annotated[
        list[StoreCatchment] | None,
        Field(
            description='Target users within store catchment areas from a synced store catalog. Each entry references a store-type catalog and optionally narrows to specific stores or catchment zones.',
            min_length=1,
        ),
    ] = None
    geo_proximity: Annotated[
        list[GeoProximityItem] | None,
        Field(
            description='Target users within travel time, distance, or a custom boundary around arbitrary geographic points. Multiple entries use OR semantics — a user within range of any listed point is eligible. For campaigns targeting 10+ locations, consider using store_catchments with a location catalog instead. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    language: Annotated[
        list[locale_tag.LanguageTag] | None,
        Field(
            description="Restrict to users with specific language preferences using canonical BCP 47 language ranges. Each buyer range is evaluated against a user's language-preference tag with RFC 4647 section 3.3.1 Basic Filtering: 'fr' matches 'fr', 'fr-CA', and 'fr-FR', while 'fr-CA' matches 'fr-CA' and more-specific descendants but not 'fr' or 'fr-FR'. Values use OR logic.",
            min_length=1,
            title='Targeting Languages',
        ),
    ] = None
    keyword_targets: Annotated[
        list[KeywordTarget] | None,
        Field(
            description='Keyword targeting for search and retail media platforms. Restricts delivery to queries matching the specified keywords. Each keyword is identified by the tuple (keyword, match_type) — the same keyword string with different match types are distinct targets. Sellers SHOULD reject duplicate (keyword, match_type) pairs within a single request. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
            title='Targeting Keywords',
        ),
    ] = None
    negative_keywords: Annotated[
        list[negative_keyword.NegativeKeyword] | None,
        Field(
            description='Keywords to exclude from delivery. Queries matching these keywords will not trigger the ad. Each negative keyword is identified by the tuple (keyword, match_type). Seller must declare support in get_adcp_capabilities.',
            min_length=1,
            title='Targeting Negative Keywords',
        ),
    ] = 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 age_restriction : AgeRestriction | None
var audience_exclude : list[str] | None
var audience_include : list[str] | None
var axe_exclude_segment : str | None
var axe_include_segment : str | None
var browser : list[BrowserFamily] | None
var browser_exclude : list[BrowserFamily] | None
var collection_list : CollectionListReference | None
var collection_list_exclude : CollectionListReference | None
var collection_selection : CollectionSelection1 | CollectionSelection2 | None
var daypart_targets : list[DaypartTarget] | None
var demographics : DemographicTargetingIntent | None
var device_platform : list[DevicePlatform] | None
var device_platform_exclude : list[DevicePlatform] | None
var device_type : list[DeviceType] | None
var device_type_exclude : list[DeviceType] | None
var frequency_cap : FrequencyCap | None
var geo_countries : list[GeoCountry] | None
var geo_countries_exclude : collections.abc.Sequence[GeoCountriesExcludeItem] | None
var geo_metros : list[GeoMetro] | None
var geo_metros_exclude : collections.abc.Sequence[GeoMetrosExcludeItem] | None
var geo_places : list[GeographicPlaceArea] | None
var geo_places_exclude : list[GeographicPlaceArea] | None
var geo_postal_areas : list[PostalArea] | None
var geo_postal_areas_exclude : collections.abc.Sequence[PostalArea] | None
var geo_proximity : list[GeoProximityItem] | None
var geo_regions : list[GeoRegion] | None
var geo_regions_exclude : collections.abc.Sequence[GeoRegionsExcludeItem] | None
var keyword_targets : list[KeywordTarget] | None
var language : list[LanguageTag] | None
var model_config
var negative_keywords : list[NegativeKeyword] | None
var placement_selection : PlacementSelection1 | PlacementSelection2 | None
var property_list : PropertyListReference | None
var property_list_exclude : PropertyListReference | None
var signal_targeting : list[SignalTargeting1 | SignalTargeting2 | SignalTargeting3] | None
var signal_targeting_groups : PackageSignalTargetingGroups | None
var store_catchments : list[StoreCatchment] | None

Inherited members

class TargetingOverlayInput (**data: Any)
Expand source code
class TargetingOverlayInput(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    geo_countries: Annotated[
        list[GeoCountry] | None,
        Field(
            description="Restrict delivery to specific countries. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').",
            min_length=1,
        ),
    ] = None
    geo_countries_exclude: Annotated[
        list[GeoCountriesExcludeItem] | None,
        Field(
            description="Exclude specific countries from delivery. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').",
            min_length=1,
        ),
    ] = None
    geo_regions: Annotated[
        list[GeoRegion] | None,
        Field(
            description='Restrict delivery to exact canonical ISO 3166-2 subdivisions (states, provinces, regions, departments, or other subdivision categories). Unknown identifiers are invalid. At create or update, sellers MUST reject unsupported identifiers and MUST NOT silently widen, drop, or partially apply the list. During get_products, a seller may instead return a sparse, buyer-reviewable targeting_resolution modification for a valid but unsupported requested outcome. Exact internal translation preserves accepted identifiers in package readback.',
            min_length=1,
        ),
    ] = None
    geo_regions_exclude: Annotated[
        list[GeoRegionsExcludeItem] | None,
        Field(
            description='Exclude exact canonical ISO 3166-2 subdivisions. Support is independent from geo_regions inclusion support. Unknown identifiers and values also present in geo_regions are invalid. At create or update, sellers MUST reject unsupported identifiers and partial application; during get_products, a seller may instead return a sparse, buyer-reviewable targeting_resolution modification for a valid but unsupported requested outcome.',
            min_length=1,
        ),
    ] = None
    geo_metros: Annotated[
        list[geo_metro.GeoMetro] | None,
        Field(
            description='Restrict delivery to specific metro areas. Each entry specifies the classification system and target values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
            title='Targeting Geo Metros',
        ),
    ] = None
    geo_metros_exclude: Annotated[
        list[GeoMetrosExcludeItem] | None,
        Field(
            description='Exclude specific metro areas from delivery. Each entry specifies the classification system and excluded values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_postal_areas: Annotated[
        list[postal_area.PostalArea] | None,
        Field(
            description='Restrict delivery to specific postal areas. Prefer the native country + postal system form. The deprecated legacy country-fused postal-system tokens remain accepted for compatibility. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_postal_areas_exclude: Annotated[
        list[postal_area.PostalArea] | None,
        Field(
            description='Exclude specific postal areas from delivery. Prefer the native country + postal system form. The deprecated legacy country-fused postal-system tokens remain accepted for compatibility. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_places: Annotated[
        list[geo_place_area.GeographicPlaceArea] | None,
        Field(
            description='Restrict delivery to catalog-backed named places. Values MUST be stable identifiers in the declared system, not display names. Sellers must declare supported systems, countries, and place types in get_adcp_capabilities and reject unsupported entries rather than silently dropping them.',
            min_length=1,
        ),
    ] = None
    geo_places_exclude: Annotated[
        list[geo_place_area.GeographicPlaceArea] | None,
        Field(
            description='Exclude catalog-backed named places. Uses the same identifier-based shape as geo_places. Sellers MUST reject overlap with geo_places for the same country, system, place_type, and value.',
            min_length=1,
        ),
    ] = None
    daypart_targets: Annotated[
        list[daypart_target.DaypartTarget] | None,
        Field(
            description='Restrict delivery to specific time windows. Each entry specifies days of week, an hour range, and an optional timezone that defaults to inventory_local. A concrete IANA zone uses one shared civil-time clock, while inventory_local evaluates each inventory unit in its seller-assigned local timezone. Entries are independent and MAY use different clocks.',
            min_length=1,
        ),
    ] = None
    axe_include_segment: Annotated[
        str | None,
        Field(
            deprecated=True,
            description='Deprecated: Use TMP provider fields instead. AXE segment ID to include for targeting.',
        ),
    ] = None
    axe_exclude_segment: Annotated[
        str | None,
        Field(
            deprecated=True,
            description='Deprecated: Use TMP provider fields instead. AXE segment ID to exclude from targeting.',
        ),
    ] = None
    audience_include: Annotated[
        list[str] | None,
        Field(
            description='Restrict delivery to members of these first-party CRM audiences. Only users present in the uploaded lists are eligible. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Not for lookalike expansion — express that intent in the campaign brief. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    audience_exclude: Annotated[
        list[str] | None,
        Field(
            description='Suppress delivery to members of these first-party CRM audiences. Matched users are excluded regardless of other targeting. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    signal_targeting_groups: package_signal_targeting_groups.PackageSignalTargetingGroups | None = (
        None
    )
    signal_targeting: Annotated[
        list[signal_targeting_1.SignalTargeting] | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Use signal_targeting_groups for package-level signal targeting. Legacy flat signal_targeting remains accepted during the SignalRef migration window but cannot express grouped include/exclude composition or product-scoped pricing.',
            min_length=1,
        ),
    ] = None
    demographics: demographic_targeting_intent.DemographicTargetingIntent | None = None
    frequency_cap: frequency_cap_1.FrequencyCap | None = None
    property_list: property_list_ref.PropertyListReference | None = None
    property_list_exclude: property_list_ref.PropertyListReference | None = None
    collection_list: collection_list_ref.CollectionListReference | None = None
    collection_list_exclude: collection_list_ref.CollectionListReference | None = None
    placement_selection: placement_selection_1.PlacementSelection | None = None
    collection_selection: collection_selection_1.CollectionSelection | None = None
    age_restriction: targeting.AgeRestriction | None = None
    device_platform: Annotated[
        list[device_platform_1.DevicePlatform] | None,
        Field(
            description='Restrict to specific platforms. Use for technical compatibility (app only works on iOS). Values from Sec-CH-UA-Platform standard, extended for CTV.',
            min_length=1,
        ),
    ] = None
    device_platform_exclude: Annotated[
        list[device_platform_1.DevicePlatform] | None,
        Field(
            description='Exclude specific operating-system platforms from delivery. When a platform appears in both device_platform and device_platform_exclude, exclusion wins. Sellers MUST reject a request they cannot enforce rather than silently dropping the exclusion.',
            min_length=1,
        ),
    ] = None
    device_type: Annotated[
        list[device_type_1.DeviceType] | None,
        Field(
            description='Restrict to specific device form factors. Use for campaigns targeting hardware categories rather than operating systems (e.g., mobile-only promotions, CTV campaigns).',
            min_length=1,
        ),
    ] = None
    device_type_exclude: Annotated[
        list[device_type_1.DeviceType] | None,
        Field(
            description='Exclude specific device form factors from delivery (e.g., exclude CTV for app-install campaigns).',
            min_length=1,
        ),
    ] = None
    browser: Annotated[
        list[browser_family.BrowserFamily] | None,
        Field(
            description='Restrict delivery to specific canonical browser families in the impression delivery and rendering environment, not the post-click landing-page browser. Values MUST NOT be inferred solely from operating system, device, web/mobile-web inventory, or placement. Values in this array use OR semantics. When browser is supplied, families not listed are ineligible: other includes a seller-recognized family that is not explicitly enumerated, while unknown includes a browser the seller cannot classify into a recognized family. When the same family appears in browser and browser_exclude, exclusion wins. Browser and device constraints intersect; a seller that cannot enforce the exact combination MUST exclude or explicitly reconfigure the product during discovery and MUST reject it at create or update rather than silently widening delivery. Browser versions and seller-native IDs are intentionally unsupported.',
            min_length=1,
        ),
    ] = None
    browser_exclude: Annotated[
        list[browser_family.BrowserFamily] | None,
        Field(
            description='Exclude specific canonical browser families from delivery. other excludes seller-recognized families that are not explicitly enumerated; unknown excludes browsers the seller cannot classify into a recognized family. When the same family appears in browser and browser_exclude, exclusion wins. Sellers MUST reject a request they cannot enforce rather than silently dropping the exclusion.',
            min_length=1,
        ),
    ] = None
    store_catchments: Annotated[
        list[StoreCatchment] | None,
        Field(
            description='Target users within store catchment areas from a synced store catalog. Each entry references a store-type catalog and optionally narrows to specific stores or catchment zones.',
            min_length=1,
        ),
    ] = None
    geo_proximity: Annotated[
        list[GeoProximityItem] | None,
        Field(
            description='Target users within travel time, distance, or a custom boundary around arbitrary geographic points. Multiple entries use OR semantics — a user within range of any listed point is eligible. For campaigns targeting 10+ locations, consider using store_catchments with a location catalog instead. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    language: Annotated[
        list[locale_tag.LanguageTag] | None,
        Field(
            description="Restrict to users with specific language preferences using canonical BCP 47 language ranges. Each buyer range is evaluated against a user's language-preference tag with RFC 4647 section 3.3.1 Basic Filtering: 'fr' matches 'fr', 'fr-CA', and 'fr-FR', while 'fr-CA' matches 'fr-CA' and more-specific descendants but not 'fr' or 'fr-FR'. Values use OR logic.",
            min_length=1,
            title='Targeting Languages',
        ),
    ] = None
    keyword_targets: Annotated[
        list[KeywordTarget] | None,
        Field(
            description='Keyword targeting for search and retail media platforms. Restricts delivery to queries matching the specified keywords. Each keyword is identified by the tuple (keyword, match_type) — the same keyword string with different match types are distinct targets. Sellers SHOULD reject duplicate (keyword, match_type) pairs within a single request. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
            title='Targeting Keywords',
        ),
    ] = None
    negative_keywords: Annotated[
        list[negative_keyword.NegativeKeyword] | None,
        Field(
            description='Keywords to exclude from delivery. Queries matching these keywords will not trigger the ad. Each negative keyword is identified by the tuple (keyword, match_type). Seller must declare support in get_adcp_capabilities.',
            min_length=1,
            title='Targeting Negative Keywords',
        ),
    ] = 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 age_restriction : AgeRestriction | None
var audience_exclude : list[str] | None
var audience_include : list[str] | None
var axe_exclude_segment : str | None
var axe_include_segment : str | None
var browser : list[BrowserFamily] | None
var browser_exclude : list[BrowserFamily] | None
var collection_list : CollectionListReference | None
var collection_list_exclude : CollectionListReference | None
var collection_selection : CollectionSelection1 | CollectionSelection2 | None
var daypart_targets : list[DaypartTarget] | None
var demographics : DemographicTargetingIntent | None
var device_platform : list[DevicePlatform] | None
var device_platform_exclude : list[DevicePlatform] | None
var device_type : list[DeviceType] | None
var device_type_exclude : list[DeviceType] | None
var frequency_cap : FrequencyCap | None
var geo_countries : list[GeoCountry] | None
var geo_countries_exclude : list[GeoCountriesExcludeItem] | None
var geo_metros : list[GeoMetro] | None
var geo_metros_exclude : list[GeoMetrosExcludeItem] | None
var geo_places : list[GeographicPlaceArea] | None
var geo_places_exclude : list[GeographicPlaceArea] | None
var geo_postal_areas : list[PostalArea] | None
var geo_postal_areas_exclude : list[PostalArea] | None
var geo_proximity : list[GeoProximityItem] | None
var geo_regions : list[GeoRegion] | None
var geo_regions_exclude : list[GeoRegionsExcludeItem] | None
var keyword_targets : list[KeywordTarget] | None
var language : list[LanguageTag] | None
var model_config
var negative_keywords : list[NegativeKeyword] | None
var placement_selection : PlacementSelection1 | PlacementSelection2 | None
var property_list : PropertyListReference | None
var property_list_exclude : PropertyListReference | None
var signal_targeting : list[SignalTargeting1 | SignalTargeting2 | SignalTargeting3] | None
var signal_targeting_groups : PackageSignalTargetingGroups | None
var store_catchments : list[StoreCatchment] | None

Inherited members

class TargetingOverlayRequirements (**data: Any)
Expand source code
class TargetingOverlayRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    geo_countries: Required | None = None
    geo_countries_exclude: Required | None = None
    geo_regions: Required | geo_region_requirement.GeographicRegionRequirement | None = None
    geo_regions_exclude: Required | geo_region_requirement.GeographicRegionRequirement | None = None
    geo_metros: MetroRequirement | None = None
    geo_metros_exclude: MetroRequirement | None = None
    geo_places: geo_place_requirement.GeographicPlaceRequirement | None = None
    geo_places_exclude: geo_place_requirement.GeographicPlaceRequirement | None = None
    geo_postal_areas: Required | positive_postal_area_support.PositivePostalAreaSupport | None = (
        None
    )
    geo_postal_areas_exclude: (
        Required | positive_postal_area_support.PositivePostalAreaSupport | None
    ) = None
    geo_proximity: Required | GeoProximity | None = None
    daypart_targets: DaypartRequirement | None = None
    audience_include: Required | None = None
    audience_exclude: Required | None = None
    signal_targeting_groups: Required | None = None
    demographics: Required | Demographics | None = None
    frequency_cap: Required | None = None
    frequency_cap_support: Annotated[
        frequency_cap_requirements.FrequencyCapRequirements | None,
        Field(
            description='Minimum structured package-cap support. Matches a broad legacy frequency_cap: true or a containing frequency_cap_support object. Mutually exclusive with a frequency_cap: true requirement, which would exclude every constrained product.'
        ),
    ] = None
    property_list: Required | None = None
    property_list_exclude: Required | None = None
    collection_list: Required | None = None
    collection_list_exclude: Required | None = None
    placement_selection: Required | None = None
    age_restriction: Required | None = None
    device_platform: Required | None = None
    device_platform_exclude: Required | None = None
    device_type: Required | None = None
    device_type_exclude: Required | None = None
    browser: BrowserRequirement | None = None
    browser_exclude: BrowserRequirement | None = None
    store_catchments: Required | None = None
    language: Required | None = None
    keyword_targets: KeywordRequirement | None = None
    negative_keywords: KeywordRequirement | None = None
    ext: ext_1.ExtensionObject | 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 age_restriction : Required | None
var audience_exclude : Required | None
var audience_include : Required | None
var browser : BrowserRequirement | None
var browser_exclude : BrowserRequirement | None
var collection_list : Required | None
var collection_list_exclude : Required | None
var daypart_targets : DaypartRequirement | None
var demographics : Required | Demographics | None
var device_platform : Required | None
var device_platform_exclude : Required | None
var device_type : Required | None
var device_type_exclude : Required | None
var ext : ExtensionObject | None
var frequency_cap : Required | None
var frequency_cap_support : FrequencyCapRequirements | None
var geo_countries : Required | None
var geo_countries_exclude : Required | None
var geo_metros : MetroRequirement | None
var geo_metros_exclude : MetroRequirement | None
var geo_places : GeographicPlaceRequirement | None
var geo_places_exclude : GeographicPlaceRequirement | None
var geo_postal_areas : Required | PositivePostalAreaSupport | None
var geo_postal_areas_exclude : Required | PositivePostalAreaSupport | None
var geo_proximity : Required | GeoProximity | None
var geo_regions : Required | GeographicRegionRequirement | None
var geo_regions_exclude : Required | GeographicRegionRequirement | None
var keyword_targets : KeywordRequirement | None
var language : Required | None
var model_config
var negative_keywords : KeywordRequirement | None
var placement_selection : Required | None
var property_list : Required | None
var property_list_exclude : Required | None
var signal_targeting_groups : Required | None
var store_catchments : Required | None

Inherited members

class TargetingOverlaySupport (**data: Any)
Expand source code
class TargetingOverlaySupport(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    geo_countries: CountrySupport | None = None
    geo_countries_exclude: CountrySupport | None = None
    geo_regions: Supported | geo_region_support.GeographicRegionSupport | None = None
    geo_regions_exclude: Supported | geo_region_support.GeographicRegionSupport | None = None
    geo_metros: MetroSupport | None = None
    geo_metros_exclude: MetroSupport | None = None
    geo_places: PlaceSupport | None = None
    geo_places_exclude: PlaceSupport | None = None
    geo_postal_areas: Supported | positive_postal_area_support.PositivePostalAreaSupport | None = (
        None
    )
    geo_postal_areas_exclude: (
        Supported | positive_postal_area_support.PositivePostalAreaSupport | None
    ) = None
    geo_proximity: Supported | GeoProximity | None = None
    daypart_targets: DaypartSupport | None = None
    audience_include: Supported | None = None
    audience_exclude: Supported | None = None
    signal_targeting_groups: Supported | None = None
    demographics: Supported | Demographics | None = None
    frequency_cap: Supported | None = None
    frequency_cap_support: Annotated[
        frequency_cap_constraints.FrequencyCapConstraints | None,
        Field(
            description='Independently positive constrained package-cap support. Mutually exclusive with legacy frequency_cap: a product declares one form or the other.'
        ),
    ] = None
    property_list: Supported | None = None
    property_list_exclude: Supported | None = None
    collection_list: Supported | None = None
    collection_list_exclude: Supported | None = None
    placement_selection: Supported | PlacementSelection | None = None
    age_restriction: Supported | None = None
    device_platform: Supported | None = None
    device_platform_exclude: Supported | None = None
    device_type: Supported | None = None
    device_type_exclude: Supported | None = None
    browser: BrowserSupport | None = None
    browser_exclude: BrowserSupport | None = None
    store_catchments: Supported | None = None
    language: Supported | None = None
    keyword_targets: KeywordSupport | None = None
    negative_keywords: KeywordSupport | None = None
    ext: ext_1.ExtensionObject | 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 age_restriction : Supported | None
var audience_exclude : Supported | None
var audience_include : Supported | None
var browser : BrowserSupport | None
var browser_exclude : BrowserSupport | None
var collection_list : Supported | None
var collection_list_exclude : Supported | None
var daypart_targets : DaypartSupport | None
var demographics : Supported | Demographics | None
var device_platform : Supported | None
var device_platform_exclude : Supported | None
var device_type : Supported | None
var device_type_exclude : Supported | None
var ext : ExtensionObject | None
var frequency_cap : Supported | None
var frequency_cap_support : FrequencyCapConstraints | None
var geo_countries : CountrySupport | None
var geo_countries_exclude : CountrySupport | None
var geo_metros : MetroSupport | None
var geo_metros_exclude : MetroSupport | None
var geo_places : PlaceSupport | None
var geo_places_exclude : PlaceSupport | None
var geo_postal_areas : Supported | PositivePostalAreaSupport | None
var geo_postal_areas_exclude : Supported | PositivePostalAreaSupport | None
var geo_proximity : Supported | GeoProximity | None
var geo_regions : Supported | GeographicRegionSupport | None
var geo_regions_exclude : Supported | GeographicRegionSupport | None
var keyword_targets : KeywordSupport | None
var language : Supported | None
var model_config
var negative_keywords : KeywordSupport | None
var placement_selection : Supported | PlacementSelection | None
var property_list : Supported | None
var property_list_exclude : Supported | None
var signal_targeting_groups : Supported | None
var store_catchments : Supported | None

Inherited members

class TargetingUnknownAgeEligibilityConstraint (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class TargetingUnknownAgeEligibilityConstraint(RootModel[Any]):
    root: Annotated[
        Any,
        Field(
            description='Unknown-age delivery cannot satisfy a minimum-age eligibility policy. When demographic audience targeting and age_restriction are both present, include_unknown must be false.',
            title='Targeting Unknown Age Eligibility Constraint',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Any]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Any
class TargetingVerifiedAgeBasisConstraint (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class TargetingVerifiedAgeBasisConstraint(RootModel[Any]):
    root: Annotated[
        Any,
        Field(
            description='A legal verification requirement always narrows demographic targeting. When the buyer supplies accepted_bases and age_restriction requires verification, verified must be accepted; otherwise the constraints have an empty intersection and the request is invalid.',
            title='Targeting Verified Age Basis Constraint',
        ),
    ]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Any]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : Any
class TasksGetRequest (**data: Any)
Expand source code
class TasksGetRequest(AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    task_id: Annotated[str, Field(description='Unique identifier of the task to retrieve')]
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account scope for the task lookup. Sellers MUST return REFERENCE_NOT_FOUND for a task_id that exists only under a different account or principal. When omitted, the seller MAY use the credential-bound singleton account, but multi-account credentials SHOULD require an explicit account.'
        ),
    ] = None
    include_history: Annotated[
        StrictBool | None,
        Field(
            description='Include full conversation history for this task (may increase response size)'
        ),
    ] = False
    include_result: Annotated[
        StrictBool | None,
        Field(
            description="Include the task's canonical terminal result payload when one exists. Defaults to false for lightweight status-only polls. When true, sellers MUST include result for completed, failed, or rejected terminal tasks when that task produced a terminal artifact; canceled tasks may have no result. The legacy singular error field remains a convenience for failed tasks but does not replace the canonical terminal result."
        ),
    ] = False
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 account : AccountReference1 | AccountReference2 | None
var context : ContextObject | None
var ext : ExtensionObject | None
var include_history : bool | None
var include_result : bool | None
var model_config
var task_id : str

Inherited members

class TasksGetResponse (**data: Any)
Expand source code
class TasksGetResponse(AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    task_id: Annotated[str, Field(description='Unique identifier for this task')]
    task_type: Annotated[task_type_1.TaskType, Field(description='Type of AdCP operation')]
    protocol: Annotated[
        adcp_protocol.AdcpProtocol, Field(description='AdCP protocol this task belongs to')
    ]
    status: Annotated[task_status.TaskStatus, Field(description='Current task status')]
    created_at: Annotated[
        AwareDatetime, Field(description='When the task was initially created (ISO 8601)')
    ]
    updated_at: Annotated[
        AwareDatetime, Field(description='When the task was last updated (ISO 8601)')
    ]
    completed_at: Annotated[
        AwareDatetime | None,
        Field(
            description='When the task completed (ISO 8601, only for completed/failed/canceled tasks)'
        ),
    ] = None
    has_webhook: Annotated[
        StrictBool | None, Field(description='Whether this task has webhook configuration')
    ] = None
    progress: Annotated[
        Progress | None, Field(description='Progress information for long-running tasks')
    ] = None
    error: Annotated[
        Error | None,
        Field(
            description='Convenience summary for failed tasks. When include_result was true and the canonical terminal result is also present, this error MUST agree with the canonical fatal error in result. A legacy poll carrying only this singular summary proves failure status but not equivalence to a richer terminal webhook artifact.'
        ),
    ] = None
    history: Annotated[
        list[HistoryItem] | None,
        Field(
            description='Complete conversation history for this task (only included if include_history was true in request)'
        ),
    ] = None
    result: Annotated[
        dict[str, Any] | None,
        Field(
            description='Canonical task-specific terminal payload. Present when include_result was true and a completed, failed, or rejected task produced a terminal artifact; canceled tasks may omit it. For failed tasks, the singular error field is a convenience summary and MUST agree with the canonical fatal error represented here. Consumers and sellers MUST resolve and validate the exact schema through manifest.task_result_resolution: use terminal_schema_overrides[task_type] when present, otherwise tools[task_type].response_schema. The polling envelope keeps this field generic so tasks/get does not embed every task response schema.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 completed_at : pydantic.types.AwareDatetime | None
var context : ContextObject | None
var created_at : pydantic.types.AwareDatetime
var error : Error | None
var ext : ExtensionObject | None
var has_webhook : bool | None
var history : list[HistoryItem] | None
var model_config
var progress : Progress | None
var protocol : AdcpProtocol
var result : dict[str, typing.Any] | None
var status : TaskStatus
var task_id : str
var task_type : TaskType
var updated_at : pydantic.types.AwareDatetime

Inherited members

class TasksListRequest (**data: Any)
Expand source code
class TasksListRequest(AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description="Account scope for task reconciliation. Sellers MUST only return tasks created for the caller's authenticated account + principal pair. When omitted, the seller MAY use the credential-bound singleton account, but multi-account credentials SHOULD require an explicit account."
        ),
    ] = None
    filters: Annotated[Filters | None, Field(description='Filter criteria for querying tasks')] = (
        None
    )
    sort: Annotated[Sort | None, Field(description='Sorting parameters')] = None
    pagination: pagination_request.PaginationRequest | None = None
    include_history: Annotated[
        StrictBool | None,
        Field(
            description='Include full conversation history for each task (may significantly increase response size)'
        ),
    ] = False
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 account : AccountReference1 | AccountReference2 | None
var context : ContextObject | None
var ext : ExtensionObject | None
var filters : Filters | None
var include_history : bool | None
var model_config
var pagination : PaginationRequest | None
var sort : Sort | None

Inherited members

class TasksListResponse (**data: Any)
Expand source code
class TasksListResponse(AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    query_summary: Annotated[
        QuerySummary, Field(description='Summary of the query that was executed')
    ]
    tasks: Annotated[list[Task], Field(description='Array of tasks matching the query criteria')]
    pagination: pagination_response.PaginationResponse
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var pagination : PaginationResponse
var query_summary : QuerySummary
var tasks : list[Task]

Inherited members

class Terms (**data: Any)
Expand source code
class Terms(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    advertiser: Annotated[
        str | None, Field(description='Advertiser name or identifier', max_length=500)
    ] = None
    publisher: Annotated[
        str | None, Field(description='Publisher name or identifier', max_length=500)
    ] = None
    total_budget: Annotated[TotalBudget | None, Field(description='Total committed budget')] = None
    flight_start: Annotated[AwareDatetime | None, Field(description='Campaign start date')] = None
    flight_end: Annotated[AwareDatetime | None, Field(description='Campaign end date')] = None
    payment_terms: Annotated[PaymentTerms | None, Field(description='Payment terms')] = 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 advertiser : str | None
var flight_end : pydantic.types.AwareDatetime | None
var flight_start : pydantic.types.AwareDatetime | None
var model_config
var payment_terms : PaymentTerms | None
var publisher : str | None
var total_budget : TotalBudget | None

Inherited members

class TextAssetRequirements (**data: Any)
Expand source code
class TextAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    min_length: Annotated[SchemaInt | None, Field(description='Minimum character length', ge=0)] = (
        None
    )
    max_length: Annotated[SchemaInt | None, Field(description='Maximum character length', ge=1)] = (
        None
    )
    min_lines: Annotated[SchemaInt | None, Field(description='Minimum number of lines', ge=1)] = (
        None
    )
    max_lines: Annotated[SchemaInt | None, Field(description='Maximum number of lines', ge=1)] = (
        None
    )
    character_pattern: Annotated[
        str | None,
        Field(
            description="Regex pattern defining allowed characters (e.g., '^[a-zA-Z0-9 .,!?-]+$')"
        ),
    ] = None
    prohibited_terms: Annotated[
        list[str] | None, Field(description='List of prohibited words or phrases')
    ] = None
    allowed_values: Annotated[
        list[str] | None,
        Field(
            description='Closed set of permitted string values for this text slot. When present, a conformant implementation MUST reject any submitted content not in this list with `CREATIVE_VALUE_NOT_ALLOWED` (echoing the offending field path in `error.field` and the allowed list in `error.details.allowed_values`). Matching is case-sensitive; producers MUST supply exact casing. If the submitted value contains unresolved template tokens (e.g., {{product_name}}), validation against allowed_values MUST be deferred until interpolation is complete. All declared constraints (allowed_values, character_pattern, max_length, etc.) are conjunctive — submitted content must satisfy every applicable constraint simultaneously.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var allowed_values : list[str] | None
var character_pattern : str | None
var max_length : int | None
var max_lines : int | None
var min_length : int | None
var min_lines : int | None
var model_config
var prohibited_terms : list[str] | None

Inherited members

class TextDecoration (**data: Any)
Expand source code
class TextDecoration(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Literal['text'] = 'text'
    layer: Layer
    bounds: Rectangle
    text: Annotated[str, Field(max_length=4096)]
    text_color: Color
    font_size: Annotated[SchemaInt, Field(ge=6, le=256)]

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 bounds : Rectangle
var font_size : int
var kind : Literal['text']
var layer : Layer
var model_config
var text : str
var text_color : Color

Inherited members

class TimeBasedView (**data: Any)
Expand source code
class TimeBasedView(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    threshold_seconds: Annotated[
        StrictFloat,
        Field(
            description='Continuous duration threshold in seconds an impression must meet to count as a view in this entry.',
            gt=0.0,
        ),
    ]
    basis: Annotated[
        view_threshold_basis.ViewThresholdBasis,
        Field(
            description='Whether the threshold clock runs on playback time or in-view time. Required because play-time and in-view counts at the same threshold are materially different numbers.'
        ),
    ]
    views: Annotated[
        StrictFloat,
        Field(description="Count of views meeting this entry's threshold and basis.", ge=0.0),
    ]
    standard: Annotated[
        viewability_standard.ViewabilityStandard | None,
        Field(
            description="Viewability standard governing the in-view clock for this entry. RECOMMENDED when basis is 'in_view' (MRC and GroupM thresholds differ); not applicable to play_time entries."
        ),
    ] = 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 basis : ViewThresholdBasis
var model_config
var standard : ViewabilityStandard | None
var threshold_seconds : float
var views : float

Inherited members

class TimeForecastDimension (**data: Any)
Expand source code
class TimeForecastDimension(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    kind: Annotated[Literal['time'], Field(description='Dimension family discriminator.')] = 'time'
    start_time: Annotated[
        AwareDatetime,
        Field(description='Inclusive window start (RFC 3339 date-time with timezone offset).'),
    ]
    end_time: Annotated[
        AwareDatetime,
        Field(
            description='Exclusive window end (RFC 3339 date-time with timezone offset). MUST be after start_time.'
        ),
    ]

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 end_time : pydantic.types.AwareDatetime
var kind : Literal['time']
var model_config
var start_time : pydantic.types.AwareDatetime

Inherited members

class TotalBudget (**data: Any)
Expand source code
class TotalBudget(AdCPBaseModel):
    amount: Annotated[StrictFloat, Field(ge=0.0)]
    currency: Annotated[
        str, Field(description='ISO 4217 currency code', max_length=3, min_length=3)
    ]

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 amount : float
var currency : str
var model_config

Inherited members

class TrackerExecutionContract (**data: Any)
Expand source code
class TrackerExecutionContract(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    complete: Annotated[
        StrictBool,
        Field(
            description='Whether honored is the complete set. complete:true with an empty honored array explicitly supports no buyer-supplied trackers.'
        ),
    ]
    honored: Annotated[
        list[tracker_execution_selector.TrackerExecutionSelector],
        Field(
            description='Exact tracker/event selectors the seller accepts and initiates once per manifest instance for each logical event occurrence. selector_id and structural selector identity are each unique within this array.'
        ),
    ]

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 complete : bool
var honored : list[TrackerExecutionSelector1 | TrackerExecutionSelector2 | TrackerExecutionSelector3]
var model_config

Inherited members

class TrackerExecutionSelector1 (**data: Any)
Expand source code
class TrackerExecutionSelector1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    selector_id: Annotated[
        str,
        Field(
            description='Stable identifier unique within the materialized execution contract.',
            min_length=1,
        ),
    ]
    asset_type: Literal['pixel_tracker'] = 'pixel_tracker'
    event: pixel_tracking_event.PixelTrackingEvent
    method: Annotated[
        Literal['img'],
        Field(
            description='AdCP 3.2 execution contracts cover image-pixel initiation only; JavaScript response evaluation is outside this contract version.'
        ),
    ] = 'img'
    custom_event_name: Annotated[
        str | None, Field(description='Required only when event is custom.', min_length=1)
    ] = None
    execution_actor: tracker_execution_actor.TrackerExecutionActor
    firing_paths: Annotated[
        list[tracker_firing_path.TrackerFiringPath],
        Field(
            description='Complete set of permitted initiation environments. Exactly one path is selected for each logical event occurrence.',
            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_type : Literal['pixel_tracker']
var custom_event_name : str | None
var event : PixelTrackingEvent
var execution_actor : TrackerExecutionActor
var firing_paths : list[TrackerFiringPath]
var method : Literal['img']
var model_config
var selector_id : str

Inherited members

class TrackerExecutionSelector2 (**data: Any)
Expand source code
class TrackerExecutionSelector2(VastTrackerConstraints):
    model_config = ConfigDict(
        extra='forbid',
    )
    selector_id: Annotated[
        str,
        Field(
            description='Stable identifier unique within the materialized execution contract.',
            min_length=1,
        ),
    ]
    asset_type: Literal['vast_tracker'] = 'vast_tracker'
    vast_versions: vast_tracker_constraints.VastVersions
    vast_event: vast_tracker_constraints.VastEvent
    target: vast_tracker_constraints.VastTarget
    offset: vast_tracker_constraints.VastOffset | None = None
    execution_actor: tracker_execution_actor.TrackerExecutionActor
    firing_paths: Annotated[
        list[tracker_firing_path.TrackerFiringPath],
        Field(
            description='Complete set of permitted initiation environments. Exactly one path is selected for each logical event occurrence.',
            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_type : Literal['vast_tracker']
var execution_actor : TrackerExecutionActor
var firing_paths : list[TrackerFiringPath]
var model_config
var offset : VastOffset | None
var selector_id : str
var target : VastTarget
var vast_event : VastEvent
var vast_versions : VastVersions

Inherited members

class TrackerExecutionSelector3 (**data: Any)
Expand source code
class TrackerExecutionSelector3(DaastTrackerConstraints):
    model_config = ConfigDict(
        extra='forbid',
    )
    selector_id: Annotated[
        str,
        Field(
            description='Stable identifier unique within the materialized execution contract.',
            min_length=1,
        ),
    ]
    asset_type: Literal['daast_tracker'] = 'daast_tracker'
    daast_versions: daast_tracker_constraints.DaastVersions
    daast_event: daast_tracker_constraints.DaastEvent
    target: daast_tracker_constraints.DaastTarget
    offset: daast_tracker_constraints.DaastOffset | None = None
    execution_actor: tracker_execution_actor.TrackerExecutionActor
    firing_paths: Annotated[
        list[tracker_firing_path.TrackerFiringPath],
        Field(
            description='Complete set of permitted initiation environments. Exactly one path is selected for each logical event occurrence.',
            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_type : Literal['daast_tracker']
var daast_event : DaastEvent
var daast_versions : DaastVersions
var execution_actor : TrackerExecutionActor
var firing_paths : list[TrackerFiringPath]
var model_config
var offset : DaastOffset | None
var selector_id : str
var target : DaastTarget

Inherited members

class Tracks (*args, **kwds)
Expand source code
class Tracks(StrEnum):
    pass_ = 'pass'  # nosec B105: Fixed protocol compliance track verdict.
    fail = 'fail'
    partial = 'partial'
    skip = 'skip'
    silent = 'silent'
    warning = 'warning'
    unknown = 'unknown'
    skipped = 'skipped'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var fail
var partial
var pass_
var silent
var skip
var skipped
var unknown
var warning
class Transformer (**data: Any)
Expand source code
class Transformer(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transformer_id: Annotated[
        str,
        Field(
            description='Stable identifier for this transformer within the agent. Pass to build_creative `transformer_id` to select it.'
        ),
    ]
    name: Annotated[
        str,
        Field(
            description="Human-readable transformer name (e.g. 'Voiceover — Isaac', 'Veo 3 text-to-video')."
        ),
    ]
    description: Annotated[
        str | None,
        Field(description='Plain-text explanation of what this transformer produces and how.'),
    ] = None
    metadata: Annotated[
        dict[str, Any] | None,
        Field(
            description='Transformer-specific attributes a buyer can filter or display (e.g. provider, modality, language).'
        ),
    ] = None
    voice_synthesis_ref: Annotated[
        list[VoiceSynthesisRefItem] | None,
        Field(
            description='Optional discovery/audit anchors for voice transformers provisioned from brand-agent voice_synthesis entries. Informational only: these references help buyers match a discovered transformer to brand/rights-agent provenance, but they do not assert build-time authorization or require the creative agent to perform rights-token validation.',
            min_length=1,
        ),
    ] = None
    input_format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named formats this transformer accepts as input. Use input_formats with canonical declarations.',
        ),
    ] = None
    output_format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named formats this transformer can produce. Use output_capability_ids.',
            min_length=1,
        ),
    ] = None
    input_formats: Annotated[
        list[InputFormat] | None,
        Field(
            description='Canonical format declarations this transformer accepts as input. Omitted means it builds from a brief or raw assets rather than transforming an existing creative. Compatibility uses canonical constraint satisfaction, not identifier equality. Transformer self-description has no seller production authority, so tracker_execution_contract and tracker_execution_contract_digest are forbidden.',
            min_length=1,
        ),
    ] = None
    output_capability_ids: Annotated[
        list[OutputCapabilityId] | None,
        Field(
            description="Canonical output capabilities this transformer can produce. Every value MUST match this agent's get_adcp_capabilities `creative.supported_formats[].capability_id`. A build_creative request's target_capability_id(s) MUST be a subset of this array.",
            min_length=1,
        ),
    ] = None
    params: Annotated[
        list[transformer_param.TransformerParam] | None,
        Field(
            description="Configuration knobs this transformer exposes. The buyer supplies values in build_creative `config`, keyed by each param's `field`. Enumerable param values (e.g. account-specific voices) are returned only when requested via list_transformers `expand_params`."
        ),
    ] = None
    pricing_options: Annotated[
        list[vendor_pricing_option.VendorPricingOption] | None,
        Field(
            description='Per-account rate-card options for using this transformer. Present when the list_transformers request set include_pricing=true with an account. The applied option is echoed back per-leaf on the build_creative response and reconciled via report_usage.',
            min_length=1,
        ),
    ] = None
    multiplicity: Annotated[
        Multiplicity | None,
        Field(
            description="Optional per-transformer fan-out limits that NARROW the agent-level get_adcp_capabilities `creative.multiplicity`. Same shape as the agent-level object. When present, this transformer's authoritative; its ceilings (max_creatives_limit / max_variants_limit) MUST NOT exceed the agent ceilings, and its variant_dimensions MUST be a subset of the agent's. Omit to inherit the agent-level capability unchanged."
        ),
    ] = None

    @model_validator(mode='after')
    def _require_output_format_declaration(self) -> Transformer:
        """At least one output declaration is required by the schema."""
        # Read Pydantic's stored values directly so validation itself does not
        # emit a deprecation warning for the still-supported legacy field.
        if (
            self.__dict__.get('output_capability_ids') is None
            and self.__dict__.get('output_format_ids') is None
        ):
            raise ValueError(
                'one of output_capability_ids or deprecated output_format_ids is required'
            )
        return self

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> Transformer:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('output_capability_ids',), ('output_format_ids',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'Transformer requires at least one of these field groups: output_capability_ids | output_format_ids'
        )

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 description : str | None
var input_format_ids : list[FormatReferenceStructuredObject] | None
var input_formats : list[InputFormat18 | InputFormat19 | InputFormat20 | InputFormat21 | InputFormat22 | InputFormat23 | InputFormat24 | InputFormat25 | InputFormat26 | InputFormat27 | InputFormat28 | InputFormat29 | InputFormat30 | InputFormat31 | InputFormat32 | InputFormat33] | None
var metadata : dict[str, typing.Any] | None
var model_config
var multiplicity : Multiplicity | None
var name : str
var output_capability_ids : list[OutputCapabilityId] | None
var output_format_ids : list[FormatReferenceStructuredObject] | None
var params : list[TransformerParam] | None
var pricing_options : list[VendorPricingOption7 | VendorPricingOption8 | VendorPricingOption9 | VendorPricingOption10 | VendorPricingOption11] | None
var transformer_id : str
var voice_synthesis_ref : list[VoiceSynthesisRefItem] | None

Inherited members

class TransformerParam (**data: Any)
Expand source code
class TransformerParam(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    field: Annotated[
        str,
        Field(
            description='The config key. Buyers set the value under this exact key in build_creative `config`.'
        ),
    ]
    type: Annotated[
        Type, Field(description='JSON type of the value the buyer supplies for this field.')
    ]
    value_source: Annotated[
        ValueSource,
        Field(
            description='Where the legal values come from. `inline` — a small closed set listed in `allowed_values` (e.g. mastering_preset). `range` — a numeric interval bounded by `minimum`/`maximum` (e.g. speaking_rate). `enumerable` — an account-scoped, dynamic set (e.g. voices, including custom/cloned ones) resolved per-credential; values appear in `options[]` only when expanded. `free_text` — an open buyer-authored string with no closed/enumerable set (e.g. a negative_prompt or style note for a generative agent); `type` MUST be `string` and `allowed_values`/`minimum`/`maximum`/`options`/`options_cursor` MUST be absent. NOTE: a transformer-param MUST NOT be a generation-count knob (sample_count/n/num_images/count) — output count is owned by `max_variants`/`max_creatives`, never config.'
        ),
    ]
    max_length: Annotated[
        SchemaInt | None,
        Field(
            description='Optional maximum character length for a `free_text` param. Omit for no declared limit.',
            ge=1,
        ),
    ] = None
    allowed_values: Annotated[
        list[Any] | None,
        Field(
            description='The closed set of legal values. Present when `value_source` is `inline`.',
            min_length=1,
        ),
    ] = None
    minimum: Annotated[
        StrictFloat | None,
        Field(description='Inclusive lower bound. Present when `value_source` is `range`.'),
    ] = None
    maximum: Annotated[
        StrictFloat | None,
        Field(description='Inclusive upper bound. Present when `value_source` is `range`.'),
    ] = None
    options: Annotated[
        list[Option] | None,
        Field(
            description="Account-scoped legal values for an `enumerable` param. Populated ONLY when this param's `field` was named in the list_transformers `expand_params` request — otherwise omitted (the buyer enumerates on demand). Brief-filtered and paginated; use `options_cursor` for the next page."
        ),
    ] = None
    options_cursor: Annotated[
        str | None,
        Field(
            description="Opaque pagination cursor for this param's `options[]`. Present when more option values are available than were returned. Pass back to list_transformers (scoped to this transformer + field) to fetch the next page."
        ),
    ] = None
    default: Annotated[
        Any | None,
        Field(
            description='The value applied when the buyer omits this field from `config`. Type matches `type`.'
        ),
    ] = None
    required: Annotated[
        StrictBool | None,
        Field(
            description='Whether the buyer MUST supply this field in `config`. When false and no `default` is declared, the agent chooses.'
        ),
    ] = False
    description: Annotated[
        str | None, Field(description='Human-readable explanation of what this knob does.')
    ] = 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 allowed_values : list[typing.Any] | None
var default : typing.Any | None
var description : str | None
var field : str
var max_length : int | None
var maximum : float | None
var minimum : float | None
var model_config
var options : list[Option] | None
var options_cursor : str | None
var required : bool | None
var type : Type
var value_source : ValueSource

Inherited members

class Transition (**data: Any)
Expand source code
class Transition(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    from_: Annotated[
        str | None,
        Field(
            alias='from',
            description="Prior status of the resource (e.g., 'ready', 'approved', 'good'). Optional — sellers SHOULD include when known, MAY omit when the resource was discovered already in an offline state (e.g., a property depublished via brand.json crawl with no prior snapshot). Open string at the schema layer because each resource_type has its own serviceable-state vocabulary; the pattern constraint blocks free-form garbage, and the impairment.coherence assertion validates that 'from' is a known serviceable value for the resource_type.",
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ] = None
    to: Annotated[
        impairment_offline_state.ImpairmentOfflineState,
        Field(
            description="Current (offline) status of the resource. Drawn from the resource_type's canonical lifecycle enum; see impairment-offline-state for per-value resource_type pairing. The pairing is validated by impairment.coherence."
        ),
    ]

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 from_ : str | None
var model_config
var to : ImpairmentOfflineState

Inherited members

class Transmission (*args, **kwds)
Expand source code
class Transmission(StrEnum):
    automatic = 'automatic'
    manual = 'manual'
    cvt = 'cvt'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var automatic
var cvt
var manual
class TruncationSentinel (**data: Any)
Expand source code
class TruncationSentinel(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    field_truncation: Annotated[
        FieldTruncation,
        Field(
            alias='_truncation',
            description='Truncation envelope. The leading underscore is a deliberate signal that this property is a control marker and not a payload field — the natural value being surfaced will not have a `_truncation` key. `additionalProperties: true` so future revisions of this contract can add classification fields without a forward-compat break.',
        ),
    ]

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 field_truncation : FieldTruncation
var model_config

Inherited members

class Trust (*args, **kwds)
Expand source code
class Trust(StrEnum):
    trusted = 'trusted'
    untrusted = 'untrusted'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var trusted
var untrusted
class UnavailableReason (*args, **kwds)
Expand source code
class UnavailableReason(StrEnum):
    deleted = 'deleted'
    purged = 'purged'
    legal_erasure = 'legal_erasure'
    access_revoked = 'access_revoked'
    other = 'other'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var access_revoked
var deleted
var legal_erasure
var other
var purged
class UniversalMacro (*args, **kwds)
Expand source code
class UniversalMacro(StrEnum):
    MEDIA_BUY_ID = 'MEDIA_BUY_ID'
    PACKAGE_ID = 'PACKAGE_ID'
    CREATIVE_ID = 'CREATIVE_ID'
    CACHEBUSTER = 'CACHEBUSTER'
    TIMESTAMP = 'TIMESTAMP'
    CLICK_URL = 'CLICK_URL'
    GDPR = 'GDPR'
    GDPR_CONSENT = 'GDPR_CONSENT'
    US_PRIVACY = 'US_PRIVACY'
    GPP_STRING = 'GPP_STRING'
    GPP_SID = 'GPP_SID'
    IP_ADDRESS = 'IP_ADDRESS'
    LIMIT_AD_TRACKING = 'LIMIT_AD_TRACKING'
    DEVICE_TYPE = 'DEVICE_TYPE'
    OS = 'OS'
    OS_VERSION = 'OS_VERSION'
    DEVICE_MAKE = 'DEVICE_MAKE'
    DEVICE_MODEL = 'DEVICE_MODEL'
    USER_AGENT = 'USER_AGENT'
    APP_BUNDLE = 'APP_BUNDLE'
    APP_NAME = 'APP_NAME'
    COUNTRY = 'COUNTRY'
    REGION = 'REGION'
    CITY = 'CITY'
    ZIP = 'ZIP'
    DMA = 'DMA'
    LAT = 'LAT'
    LONG = 'LONG'
    DEVICE_ID = 'DEVICE_ID'
    DEVICE_ID_TYPE = 'DEVICE_ID_TYPE'
    DOMAIN = 'DOMAIN'
    PAGE_URL = 'PAGE_URL'
    REFERRER = 'REFERRER'
    KEYWORDS = 'KEYWORDS'
    PLACEMENT_ID = 'PLACEMENT_ID'
    FOLD_POSITION = 'FOLD_POSITION'
    AD_WIDTH = 'AD_WIDTH'
    AD_HEIGHT = 'AD_HEIGHT'
    VIDEO_ID = 'VIDEO_ID'
    VIDEO_TITLE = 'VIDEO_TITLE'
    VIDEO_DURATION = 'VIDEO_DURATION'
    VIDEO_CATEGORY = 'VIDEO_CATEGORY'
    CONTENT_GENRE = 'CONTENT_GENRE'
    CONTENT_RATING = 'CONTENT_RATING'
    PLAYER_WIDTH = 'PLAYER_WIDTH'
    PLAYER_HEIGHT = 'PLAYER_HEIGHT'
    POD_POSITION = 'POD_POSITION'
    POD_SIZE = 'POD_SIZE'
    AD_BREAK_ID = 'AD_BREAK_ID'
    STATION_ID = 'STATION_ID'
    COLLECTION_NAME = 'COLLECTION_NAME'
    INSTALLMENT_ID = 'INSTALLMENT_ID'
    AUDIO_DURATION = 'AUDIO_DURATION'
    TMPX = 'TMPX'
    IMPRESSION_ID = 'IMPRESSION_ID'
    AXEM = 'AXEM'
    CATALOG_ID = 'CATALOG_ID'
    SKU = 'SKU'
    GTIN = 'GTIN'
    OFFERING_ID = 'OFFERING_ID'
    JOB_ID = 'JOB_ID'
    HOTEL_ID = 'HOTEL_ID'
    FLIGHT_ID = 'FLIGHT_ID'
    VEHICLE_ID = 'VEHICLE_ID'
    LISTING_ID = 'LISTING_ID'
    STORE_ID = 'STORE_ID'
    PROGRAM_ID = 'PROGRAM_ID'
    DESTINATION_ID = 'DESTINATION_ID'
    CREATIVE_VARIANT_ID = 'CREATIVE_VARIANT_ID'
    APP_ITEM_ID = 'APP_ITEM_ID'
    ITEM_NAME = 'ITEM_NAME'
    ITEM_DESCRIPTION = 'ITEM_DESCRIPTION'
    ITEM_TAGLINE = 'ITEM_TAGLINE'
    ITEM_PRICE = 'ITEM_PRICE'
    ITEM_PRICE_CURRENCY = 'ITEM_PRICE_CURRENCY'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var AD_BREAK_ID
var AD_HEIGHT
var AD_WIDTH
var APP_BUNDLE
var APP_ITEM_ID
var APP_NAME
var AUDIO_DURATION
var AXEM
var CACHEBUSTER
var CATALOG_ID
var CITY
var CLICK_URL
var COLLECTION_NAME
var CONTENT_GENRE
var CONTENT_RATING
var COUNTRY
var CREATIVE_ID
var CREATIVE_VARIANT_ID
var DESTINATION_ID
var DEVICE_ID
var DEVICE_ID_TYPE
var DEVICE_MAKE
var DEVICE_MODEL
var DEVICE_TYPE
var DMA
var DOMAIN
var FLIGHT_ID
var FOLD_POSITION
var GDPR
var GPP_SID
var GPP_STRING
var GTIN
var HOTEL_ID
var IMPRESSION_ID
var INSTALLMENT_ID
var IP_ADDRESS
var ITEM_DESCRIPTION
var ITEM_NAME
var ITEM_PRICE
var ITEM_PRICE_CURRENCY
var ITEM_TAGLINE
var JOB_ID
var KEYWORDS
var LAT
var LIMIT_AD_TRACKING
var LISTING_ID
var LONG
var MEDIA_BUY_ID
var OFFERING_ID
var OS
var OS_VERSION
var PACKAGE_ID
var PAGE_URL
var PLACEMENT_ID
var PLAYER_HEIGHT
var PLAYER_WIDTH
var POD_POSITION
var POD_SIZE
var PROGRAM_ID
var REFERRER
var REGION
var SKU
var STATION_ID
var STORE_ID
var TIMESTAMP
var TMPX
var USER_AGENT
var US_PRIVACY
var VEHICLE_ID
var VIDEO_CATEGORY
var VIDEO_DURATION
var VIDEO_ID
var VIDEO_TITLE
var ZIP
class UnknownHandling (*args, **kwds)
Expand source code
class UnknownHandling(StrEnum):
    selectable = 'selectable'
    always_excluded = 'always_excluded'
    always_included = 'always_included'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var always_excluded
var always_included
var selectable
class UpdateFrequency (*args, **kwds)
Expand source code
class UpdateFrequency(StrEnum):
    realtime = 'realtime'
    hourly = 'hourly'
    daily = 'daily'
    weekly = 'weekly'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var daily
var hourly
var realtime
var weekly
class UpdateMediaBuyInputRequired (**data: Any)
Expand source code
class UpdateMediaBuyInputRequired(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    reason: Annotated[
        Reason | None, Field(description='Reason code indicating why input is needed')
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var reason : Reason | None

Inherited members

class UpdateMediaBuySubmitted (**data: Any)
Expand source code
class UpdateMediaBuySubmitted(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    status: Annotated[
        Literal['submitted'],
        Field(
            description='Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose media_buy_id is issued in-line. See task-status.json for the full task-status enum.'
        ),
    ] = 'submitted'
    task_id: Annotated[
        str,
        Field(
            description='Task handle the buyer uses with get_task_status (or the legacy AdCP tasks/get alias), and that the seller references on push-notification callbacks. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A Task id.'
        ),
    ]
    message: Annotated[
        str | None,
        Field(
            description="Optional human-readable explanation of why the task is submitted — e.g., 'Awaiting operator re-approval; typical turnaround 2–4 hours.' Plain text only. Buyers MUST treat this as untrusted seller input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile seller may inject prompt-injection payloads aimed at the buyer's agent.",
            max_length=2000,
        ),
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories, governance observations). Terminal failures belong in the error branch, not here.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal['submitted']
var task_id : str

Inherited members

class UpdateMediaBuyWorking (**data: Any)
Expand source code
class UpdateMediaBuyWorking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    percentage: Annotated[
        StrictFloat | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0)
    ] = None
    current_step: Annotated[
        str | None, Field(description='Current step or phase of the operation')
    ] = None
    total_steps: Annotated[
        SchemaInt | None, Field(description='Total number of steps in the operation', ge=1)
    ] = None
    step_number: Annotated[SchemaInt | None, Field(description='Current step number', ge=1)] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | 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 context : ContextObject | None
var current_step : str | None
var ext : ExtensionObject | None
var model_config
var percentage : float | None
var step_number : int | None
var total_steps : int | None

Inherited members

class UrlAssetRequirements (**data: Any)
Expand source code
class UrlAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    role: Annotated[
        Role | None,
        Field(
            description="Purpose this URL slot serves in the format — distinct from `url_type` on the manifest-side asset (which declares the receiver's invocation mechanism). A slot can be `click_tracker` (purpose) and accept a `tracker_pixel` (mechanism) URL, or `clickthrough` (purpose) and accept a `clickthrough` (mechanism) URL. Complements `asset_role` (human-readable label) by providing a machine-readable enum and serves as the receiver's fallback signal when a manifest URL asset omits `url_type`."
        ),
    ] = None
    protocols: Annotated[
        list[Protocol] | None,
        Field(description='Allowed URL protocols. HTTPS is recommended for all ad URLs.'),
    ] = None
    allowed_domains: Annotated[
        list[str] | None, Field(description='List of allowed domains for the URL')
    ] = None
    max_length: Annotated[
        SchemaInt | None, Field(description='Maximum URL length in characters', ge=1)
    ] = None
    macro_support: Annotated[
        StrictBool | None,
        Field(
            description="Coarse slot gate for macro-bearing URLs. `false` is a hard prohibition on macro tokens. `true` permits tokens but does not prove any dialect semantic, resolver, context, or encoding capability; exact support comes from the selected format option's macro_resolution_capabilities."
        ),
    ] = 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 allowed_domains : list[str] | None
var macro_support : bool | None
var max_length : int | None
var model_config
var protocols : list[Protocol] | None
var role : Role | None

Inherited members

class UrlAssetType (*args, **kwds)
Expand source code
class UrlAssetType(StrEnum):
    clickthrough = 'clickthrough'
    ad_request = 'ad_request'
    tracker_pixel = 'tracker_pixel'
    tracker_script = 'tracker_script'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var ad_request
var clickthrough
var tracker_pixel
var tracker_script
class UserMatch (**data: Any)
Expand source code
class UserMatch(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    uids: Annotated[
        list[Uid] | None, Field(description='Universal ID values for user matching', min_length=1)
    ] = None
    hashed_email: Annotated[
        str | None,
        Field(
            description='SHA-256 hash of lowercase, trimmed email address. Buyer must normalize before hashing: lowercase, trim whitespace. Pseudonymous PII, not anonymous — the email namespace is small enough that an unsalted SHA-256 is recoverable via precomputed dictionaries. Treat as PII for retention, consent, and access-control purposes. See docs/reference/privacy-considerations#unsalted-hashed-identifiers-are-pseudonymous-not-anonymous.',
            pattern='^[a-f0-9]{64}$',
        ),
    ] = None
    hashed_phone: Annotated[
        str | None,
        Field(
            description='SHA-256 hash of E.164-formatted phone number (e.g. +12065551234). Buyer must normalize to E.164 before hashing. Pseudonymous PII, not anonymous — the E.164 namespace is small enough that an unsalted SHA-256 is recoverable via precomputed dictionaries. Treat as PII for retention, consent, and access-control purposes. See docs/reference/privacy-considerations#unsalted-hashed-identifiers-are-pseudonymous-not-anonymous.',
            pattern='^[a-f0-9]{64}$',
        ),
    ] = None
    click_id: Annotated[
        str | None,
        Field(description='Platform click identifier (fbclid, gclid, ttclid, ScCid, etc.)'),
    ] = None
    click_id_type: Annotated[
        str | None,
        Field(description='Type of click identifier (e.g. fbclid, gclid, ttclid, msclkid, ScCid)'),
    ] = None
    client_ip: Annotated[
        str | None, Field(description='Client IP address for probabilistic matching')
    ] = None
    client_user_agent: Annotated[
        str | None, Field(description='Client user agent string for probabilistic matching')
    ] = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> UserMatch:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('uids',), ('hashed_email',), ('hashed_phone',), ('click_id',), ('client_ip', 'client_user_agent'),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'UserMatch requires at least one of these field groups: uids | hashed_email | hashed_phone | click_id | client_ip+client_user_agent'
        )

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 click_id : str | None
var click_id_type : str | None
var client_ip : str | None
var client_user_agent : str | None
var ext : ExtensionObject | None
var hashed_email : str | None
var hashed_phone : str | None
var model_config
var uids : list[Uid] | None

Inherited members

class ValidityHint (**data: Any)
Expand source code
class ValidityHint(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    not_before: AwareDatetime | None = None
    expires_at: AwareDatetime | 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 expires_at : pydantic.types.AwareDatetime | None
var model_config
var not_before : pydantic.types.AwareDatetime | None

Inherited members

class ValueSource (*args, **kwds)
Expand source code
class ValueSource(StrEnum):
    inline = 'inline'
    range = 'range'
    enumerable = 'enumerable'
    free_text = 'free_text'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var enumerable
var free_text
var inline
var range
class VariableType (*args, **kwds)
Expand source code
class VariableType(StrEnum):
    text = 'text'
    image = 'image'
    video = 'video'
    audio = 'audio'
    url = 'url'
    number = 'number'
    boolean = 'boolean'
    color = 'color'
    date = 'date'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var audio
var boolean
var color
var date
var image
var number
var text
var url
var video
class VariantDimension (*args, **kwds)
Expand source code
class VariantDimension(StrEnum):
    voice = 'voice'
    theme = 'theme'
    best_of_n = 'best_of_n'
    transformer_config = 'transformer_config'
    custom = 'custom'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var best_of_n
var custom
var theme
var transformer_config
var voice
class Variants1 (**data: Any)
Expand source code
class Variants1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    locale_variant_id: Annotated[
        str,
        Field(
            description='Buyer-assigned stable locale-variant identity from the request.',
            max_length=255,
            min_length=1,
        ),
    ]
    locale: locale_tag.LanguageTag
    role: Literal['source'] = 'source'
    assets: ResolvedAssets

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 assets : ResolvedAssets
var locale : LanguageTag
var locale_variant_id : str
var model_config
var role : Literal['source']

Inherited members

class Variants2 (**data: Any)
Expand source code
class Variants2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    locale_variant_id: Annotated[
        str,
        Field(
            description='Buyer-assigned stable locale-variant identity from the request.',
            max_length=255,
            min_length=1,
        ),
    ]
    locale: locale_tag.LanguageTag
    role: Literal['target'] = 'target'
    assets: ResolvedAssets

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 assets : ResolvedAssets
var locale : LanguageTag
var locale_variant_id : str
var model_config
var role : Literal['target']

Inherited members

class VastAsset1 (**data: Any)
Expand source code
class VastAsset1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['vast'],
        Field(
            description='Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'vast'
    vast_version: Annotated[
        VastVersion | None,
        Field(
            description='Exact VAST version declared by the supplied URL response or inline document. Required by the 3.2 canonical `video_vast` and `audio_vast` manifest paths; optional only on the deprecated named-format compatibility path. Receivers MUST NOT relabel or synthesize a newer version merely because the destination accepts it.'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='One declaration per exact occurrence in a field carried by this asset. A URL-delivered asset can declare only occurrences in its locator `url`; tokens discovered later in a fetched VAST response require document validation evidence or an inline/snapshotted asset and MUST NOT be guessed from the locator. IAB tokens cite a registry namespace and revision rather than copying the live registry into AdCP.',
            min_length=1,
        ),
    ] = None
    vpaid_enabled: Annotated[
        StrictBool | None,
        Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected media duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[VastTrackingEvent] | None,
        Field(description='Tracking events supported by this VAST tag'),
    ] = None
    captions_url: Annotated[
        AnyUrl | None, Field(description='URL to captions file (WebVTT, SRT, etc.)')
    ] = None
    audio_description_url: Annotated[
        AnyUrl | None,
        Field(description='URL to audio description track for visually impaired users'),
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    delivery_type: Annotated[
        Literal['url'],
        Field(description='Discriminator indicating VAST is delivered via URL endpoint'),
    ] = 'url'
    url: Annotated[
        MacroBearingUrl,
        Field(
            description='URL endpoint returning VAST XML. Macro delimiters remain byte-preserved; declarations distinguish occurrences in this locator URL from occurrences in inline or fetched VAST content.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['vast']
var audio_description_url : pydantic.networks.AnyUrl | None
var captions_url : pydantic.networks.AnyUrl | None
var delivery_type : Literal['url']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[VastTrackingEvent] | None
var url : str | MacroBearingUrl1 | MacroBearingUrl2
var vast_version : VastVersion | None
var vpaid_enabled : bool | None

Inherited members

class VastAsset2 (**data: Any)
Expand source code
class VastAsset2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['vast'],
        Field(
            description='Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'vast'
    vast_version: Annotated[
        VastVersion | None,
        Field(
            description='Exact VAST version declared by the supplied URL response or inline document. Required by the 3.2 canonical `video_vast` and `audio_vast` manifest paths; optional only on the deprecated named-format compatibility path. Receivers MUST NOT relabel or synthesize a newer version merely because the destination accepts it.'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration1] | None,
        Field(
            description='One declaration per exact occurrence in a field carried by this asset. A URL-delivered asset can declare only occurrences in its locator `url`; tokens discovered later in a fetched VAST response require document validation evidence or an inline/snapshotted asset and MUST NOT be guessed from the locator. IAB tokens cite a registry namespace and revision rather than copying the live registry into AdCP.',
            min_length=1,
        ),
    ] = None
    vpaid_enabled: Annotated[
        StrictBool | None,
        Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected media duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[VastTrackingEvent] | None,
        Field(description='Tracking events supported by this VAST tag'),
    ] = None
    captions_url: Annotated[
        AnyUrl | None, Field(description='URL to captions file (WebVTT, SRT, etc.)')
    ] = None
    audio_description_url: Annotated[
        AnyUrl | None,
        Field(description='URL to audio description track for visually impaired users'),
    ] = None
    provenance: Annotated[
        Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    delivery_type: Annotated[
        Literal['inline'],
        Field(description='Discriminator indicating VAST is delivered as inline XML content'),
    ] = 'inline'
    content: Annotated[str, Field(description='Inline VAST XML content')]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['vast']
var audio_description_url : pydantic.networks.AnyUrl | None
var captions_url : pydantic.networks.AnyUrl | None
var content : str
var delivery_type : Literal['inline']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration1] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[VastTrackingEvent] | None
var vast_version : VastVersion | None
var vpaid_enabled : bool | None

Inherited members

class VastAsset3 (**data: Any)
Expand source code
class VastAsset3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['vast'],
        Field(
            description='Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'vast'
    vast_version: Annotated[
        vast_version_1.VastVersion | None,
        Field(
            description='Exact VAST version declared by the supplied URL response or inline document. Required by the 3.2 canonical `video_vast` and `audio_vast` manifest paths; optional only on the deprecated named-format compatibility path. Receivers MUST NOT relabel or synthesize a newer version merely because the destination accepts it.'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='One declaration per exact occurrence in a field carried by this asset. A URL-delivered asset can declare only occurrences in its locator `url`; tokens discovered later in a fetched VAST response require document validation evidence or an inline/snapshotted asset and MUST NOT be guessed from the locator. IAB tokens cite a registry namespace and revision rather than copying the live registry into AdCP.',
            min_length=1,
        ),
    ] = None
    vpaid_enabled: Annotated[
        StrictBool | None,
        Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected media duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[vast_tracking_event.VastTrackingEvent] | None,
        Field(description='Tracking events supported by this VAST tag'),
    ] = None
    captions_url: Annotated[
        AnyUrl | None, Field(description='URL to captions file (WebVTT, SRT, etc.)')
    ] = None
    audio_description_url: Annotated[
        AnyUrl | None,
        Field(description='URL to audio description track for visually impaired users'),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    delivery_type: Annotated[
        Literal['url'],
        Field(description='Discriminator indicating VAST is delivered via URL endpoint'),
    ] = 'url'
    url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='URL endpoint returning VAST XML. Macro delimiters remain byte-preserved; declarations distinguish occurrences in this locator URL from occurrences in inline or fetched VAST content.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['vast']
var audio_description_url : pydantic.networks.AnyUrl | None
var captions_url : pydantic.networks.AnyUrl | None
var delivery_type : Literal['url']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[VastTrackingEvent] | None
var url : str | MacroBearingUrl3 | MacroBearingUrl4
var vast_version : VastVersion | None
var vpaid_enabled : bool | None

Inherited members

class VastAsset4 (**data: Any)
Expand source code
class VastAsset4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['vast'],
        Field(
            description='Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'vast'
    vast_version: Annotated[
        vast_version_1.VastVersion | None,
        Field(
            description='Exact VAST version declared by the supplied URL response or inline document. Required by the 3.2 canonical `video_vast` and `audio_vast` manifest paths; optional only on the deprecated named-format compatibility path. Receivers MUST NOT relabel or synthesize a newer version merely because the destination accepts it.'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration20] | None,
        Field(
            description='One declaration per exact occurrence in a field carried by this asset. A URL-delivered asset can declare only occurrences in its locator `url`; tokens discovered later in a fetched VAST response require document validation evidence or an inline/snapshotted asset and MUST NOT be guessed from the locator. IAB tokens cite a registry namespace and revision rather than copying the live registry into AdCP.',
            min_length=1,
        ),
    ] = None
    vpaid_enabled: Annotated[
        StrictBool | None,
        Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Expected media duration in milliseconds (if known)', ge=0),
    ] = None
    tracking_events: Annotated[
        list[vast_tracking_event.VastTrackingEvent] | None,
        Field(description='Tracking events supported by this VAST tag'),
    ] = None
    captions_url: Annotated[
        AnyUrl | None, Field(description='URL to captions file (WebVTT, SRT, etc.)')
    ] = None
    audio_description_url: Annotated[
        AnyUrl | None,
        Field(description='URL to audio description track for visually impaired users'),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None
    delivery_type: Annotated[
        Literal['inline'],
        Field(description='Discriminator indicating VAST is delivered as inline XML content'),
    ] = 'inline'
    content: Annotated[str, Field(description='Inline VAST XML content')]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['vast']
var audio_description_url : pydantic.networks.AnyUrl | None
var captions_url : pydantic.networks.AnyUrl | None
var content : str
var delivery_type : Literal['inline']
var duration_ms : int | None
var macro_declarations : list[MacroDeclaration20] | None
var model_config
var provenance : Provenance | None
var tracking_events : list[VastTrackingEvent] | None
var vast_version : VastVersion | None
var vpaid_enabled : bool | None

Inherited members

class VastAssetRequirements (**data: Any)
Expand source code
class VastAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    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
    vast_versions: Annotated[
        list[vast_version_1.VastVersion] | None,
        Field(description='Accepted VAST version set for this asset requirement.', min_length=1),
    ] = None
    media_file_requirements: Annotated[
        vast_media_file_requirements.VastMediafileRequirements | None,
        Field(
            description='Technical acceptance constraints for the alternative MediaFile renditions in each applicable resolved InLine linear 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

Class variables

var media_file_requirements : VastMediafileRequirements | None
var model_config
var vast_version : VastVersion | None
var vast_versions : list[VastVersion] | None

Inherited members

class VastEvent (*args, **kwds)
Expand source code
class VastEvent(StrEnum):
    creativeView = 'creativeView'
    loaded = 'loaded'
    start = 'start'
    firstQuartile = 'firstQuartile'
    midpoint = 'midpoint'
    thirdQuartile = 'thirdQuartile'
    complete = 'complete'
    mute = 'mute'
    unmute = 'unmute'
    pause = 'pause'
    resume = 'resume'
    rewind = 'rewind'
    skip = 'skip'
    playerExpand = 'playerExpand'
    playerCollapse = 'playerCollapse'
    fullscreen = 'fullscreen'
    exitFullscreen = 'exitFullscreen'
    progress = 'progress'
    acceptInvitation = 'acceptInvitation'
    adExpand = 'adExpand'
    adCollapse = 'adCollapse'
    minimize = 'minimize'
    overlayViewDuration = 'overlayViewDuration'
    otherAdInteraction = 'otherAdInteraction'
    interactiveStart = 'interactiveStart'
    close = 'close'
    closeLinear = 'closeLinear'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var acceptInvitation
var adCollapse
var adExpand
var close
var closeLinear
var complete
var creativeView
var exitFullscreen
var firstQuartile
var fullscreen
var interactiveStart
var loaded
var midpoint
var minimize
var mute
var otherAdInteraction
var overlayViewDuration
var pause
var playerCollapse
var playerExpand
var progress
var resume
var rewind
var skip
var start
var thirdQuartile
var unmute
class VastMediafileRequirements (**data: Any)
Expand source code
class VastMediafileRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    delivery_methods: Annotated[
        list[vast_media_delivery_method.VastMediaDeliveryMethod] | None,
        Field(
            description='Accepted values of the required `MediaFile@delivery` attribute. `progressive` identifies a directly downloadable media file; `streaming` identifies a streaming media resource.',
            min_length=1,
        ),
    ] = None
    mime_types: Annotated[
        list[MimeType] | None,
        Field(
            description='Accepted MIME types from `MediaFile@type`, compared case-insensitively after trimming optional whitespace. Parameters are not accepted in this field. Examples: `video/mp4`, `video/webm`, `audio/mpeg`, `audio/aac`.',
            min_length=1,
        ),
    ] = None
    containers: Annotated[
        list[Container] | None,
        Field(
            description='Accepted normalized container identifiers, such as `mp4`, `webm`, or `mpeg_ts`. A receiver MUST determine the container from authoritative metadata or safe byte inspection and MUST NOT guess it only from the media URI suffix.',
            min_length=1,
        ),
    ] = None
    codecs: Annotated[
        list[Codec] | None,
        Field(
            description='Accepted codec identifiers for `MediaFile@codec`, using the codec syntax referenced by the applicable VAST version. A missing codec attribute does not satisfy a declared codec constraint unless safe inspection establishes the codec.',
            min_length=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None, Field(description='Minimum accepted `MediaFile@width` in pixels.', ge=1)
    ] = None
    max_width: Annotated[
        SchemaInt | None, Field(description='Maximum accepted `MediaFile@width` in pixels.', ge=1)
    ] = None
    min_height: Annotated[
        SchemaInt | None, Field(description='Minimum accepted `MediaFile@height` in pixels.', ge=1)
    ] = None
    max_height: Annotated[
        SchemaInt | None, Field(description='Maximum accepted `MediaFile@height` in pixels.', ge=1)
    ] = None
    min_bitrate_kbps: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted MediaFile bitrate in kilobits per second. A fixed `MediaFile@bitrate` must be at least this value. For adaptive/streaming media, the declared `MediaFile@minBitrate` must be at least this value. Safe byte inspection may establish the value when metadata is absent.',
            ge=1,
        ),
    ] = None
    max_bitrate_kbps: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted MediaFile bitrate in kilobits per second. A fixed `MediaFile@bitrate` must not exceed this value. For adaptive/streaming media, the declared `MediaFile@maxBitrate` must not exceed this value. Safe byte inspection may establish the value when metadata is absent.',
            ge=1,
        ),
    ] = None
    max_file_size_bytes: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted MediaFile size in exact bytes. `MediaFile@fileSize`, when present, is expressed in bytes; a receiver MAY verify it against safely fetched media bytes and MUST use the verified byte count if the values disagree.',
            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

Class variables

var codecs : list[Codec] | None
var containers : list[Container] | None
var delivery_methods : list[VastMediaDeliveryMethod] | None
var max_bitrate_kbps : int | None
var max_file_size_bytes : int | None
var max_height : int | None
var max_width : int | None
var mime_types : list[MimeType] | None
var min_bitrate_kbps : int | None
var min_height : int | None
var min_width : int | None
var model_config

Inherited members

class VastOffset (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class VastOffset(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^(\\d{2}:[0-5]\\d:[0-5]\\d(\\.\\d{3})?|(100|\\d{1,2})%)$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class VastTarget (*args, **kwds)
Expand source code
class VastTarget(StrEnum):
    linear = 'linear'
    non_linear = 'non_linear'
    companion = 'companion'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var companion
var linear
var non_linear
class VastTrackerConstraints (**data: Any)
Expand source code
class VastTrackerConstraints(AdCPBaseModel):
    vast_event: VastEvent | None = None
    target: VastTarget | None = VastTarget.linear
    offset: VastOffset | None = None
    vast_versions: VastVersions | 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

Subclasses

Class variables

var model_config
var offset : VastOffset | None
var target : VastTarget | None
var vast_event : VastEvent | None
var vast_versions : VastVersions | None

Inherited members

class VastTrackingEvent (*args, **kwds)
Expand source code
class VastTrackingEvent(StrEnum):
    impression = 'impression'
    creativeView = 'creativeView'
    loaded = 'loaded'
    start = 'start'
    firstQuartile = 'firstQuartile'
    midpoint = 'midpoint'
    thirdQuartile = 'thirdQuartile'
    complete = 'complete'
    mute = 'mute'
    unmute = 'unmute'
    pause = 'pause'
    resume = 'resume'
    rewind = 'rewind'
    skip = 'skip'
    playerExpand = 'playerExpand'
    playerCollapse = 'playerCollapse'
    fullscreen = 'fullscreen'
    exitFullscreen = 'exitFullscreen'
    progress = 'progress'
    acceptInvitation = 'acceptInvitation'
    adExpand = 'adExpand'
    adCollapse = 'adCollapse'
    minimize = 'minimize'
    overlayViewDuration = 'overlayViewDuration'
    otherAdInteraction = 'otherAdInteraction'
    interactiveStart = 'interactiveStart'
    clickTracking = 'clickTracking'
    customClick = 'customClick'
    close = 'close'
    closeLinear = 'closeLinear'
    error = 'error'
    viewable = 'viewable'
    notViewable = 'notViewable'
    viewUndetermined = 'viewUndetermined'
    measurableImpression = 'measurableImpression'
    viewableImpression = 'viewableImpression'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var acceptInvitation
var adCollapse
var adExpand
var clickTracking
var close
var closeLinear
var complete
var creativeView
var customClick
var error
var exitFullscreen
var firstQuartile
var fullscreen
var impression
var interactiveStart
var loaded
var measurableImpression
var midpoint
var minimize
var mute
var notViewable
var otherAdInteraction
var overlayViewDuration
var pause
var playerCollapse
var playerExpand
var progress
var resume
var rewind
var skip
var start
var thirdQuartile
var unmute
var viewUndetermined
var viewable
var viewableImpression
class VastVersion (*args, **kwds)
Expand source code
class VastVersion(StrEnum):
    field_2_0 = '2.0'
    field_3_0 = '3.0'
    field_4_0 = '4.0'
    field_4_1 = '4.1'
    field_4_2 = '4.2'
    field_4_3 = '4.3'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var field_2_0
var field_3_0
var field_4_0
var field_4_1
var field_4_2
var field_4_3
class VastVersions (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class VastVersions(RootModel[list[vast_version.VastVersion]]):
    root: Annotated[list[vast_version.VastVersion], Field(min_length=1)]

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[list[VastVersion]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : list[VastVersion]
class VehicleItem (**data: Any)
Expand source code
class VehicleItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    vehicle_id: Annotated[str, Field(description='Unique identifier for this vehicle listing.')]
    title: Annotated[str, Field(description="Listing title (e.g., '2024 Honda Civic EX Sedan').")]
    make: Annotated[str, Field(description="Vehicle manufacturer (e.g., 'Honda', 'Ford', 'BMW').")]
    model: Annotated[str, Field(description="Vehicle model (e.g., 'Civic', 'F-150', 'X5').")]
    year: Annotated[SchemaInt, Field(description='Model year.', ge=1900)]
    price: Annotated[price_1.Price | None, Field(description='Vehicle price.')] = None
    condition: Annotated[Condition | None, Field(description='Vehicle condition.')] = None
    vin: Annotated[
        str | None, Field(description='Vehicle Identification Number (17-character VIN).')
    ] = None
    trim: Annotated[
        str | None, Field(description="Trim level (e.g., 'EX', 'Limited', 'Sport').")
    ] = None
    mileage: Annotated[Mileage | None, Field(description='Odometer reading.')] = None
    body_style: Annotated[BodyStyle | None, Field(description='Vehicle body style.')] = None
    transmission: Annotated[Transmission | None, Field(description='Transmission type.')] = None
    fuel_type: Annotated[FuelType | None, Field(description='Fuel or powertrain type.')] = None
    exterior_color: Annotated[str | None, Field(description='Exterior color.')] = None
    interior_color: Annotated[str | None, Field(description='Interior color.')] = None
    location: Annotated[Location | None, Field(description='Dealer or vehicle location.')] = None
    image_url: Annotated[AnyUrl | None, Field(description='Primary vehicle image URL.')] = None
    url: Annotated[AnyUrl | None, Field(description='Vehicle listing page URL.')] = None
    tags: Annotated[
        list[str] | None,
        Field(
            description="Tags for filtering (e.g., 'low-mileage', 'one-owner', 'dealer-certified').",
            min_length=1,
        ),
    ] = None
    assets: Annotated[
        list[offering_asset_group.OfferingAssetGroup] | None,
        Field(
            description="Typed creative asset pools for this vehicle. Uses the same OfferingAssetGroup structure as offering-type catalogs. Standard group IDs: 'images_landscape' (exterior hero), 'images_vertical' (9:16 for Stories), 'images_square' (1:1). Enables formats to declare typed image requirements that map unambiguously to the right asset regardless of platform.",
            min_length=1,
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 assets : list[OfferingAssetGroup] | None
var body_style : BodyStyle | None
var condition : Condition | None
var ext : ExtensionObject | None
var exterior_color : str | None
var fuel_type : FuelType | None
var image_url : pydantic.networks.AnyUrl | None
var interior_color : str | None
var location : Location | None
var make : str
var mileage : Mileage | None
var model : str
var model_config
var price : Price | None
var tags : list[str] | None
var title : str
var transmission : Transmission | None
var trim : str | None
var url : pydantic.networks.AnyUrl | None
var vehicle_id : str
var vin : str | None
var year : int

Inherited members

class VendorMetricId (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class VendorMetricId(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 64, 'min_length': 1, 'pattern': '^[a-z][a-z0-9_]*$'}
    _json_schema_extra = {
        'description': "Identifier for a vendor-defined metric within the vendor's vocabulary. Stable lookup key; the vendor publishes the canonical list (with category, methodology, and standard alignment) in `brand.json` `agents[type='measurement']`. Lowercase with underscores so a future enum promotion into `available-metric.json` is a literal string lift. Identifier is namespaced by the vendor — the same `metric_id` may mean different things in different vendors' vocabularies.",
        'examples': ['attention_units', 'gco2e_per_impression', 'demographic_reach', 'co_view_index', 'incremental_lift_percent'],
        'title': 'Vendor Metric ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class VendorMetricOptimization (**data: Any)
Expand source code
class VendorMetricOptimization(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    supported_metrics: Annotated[
        list[vendor_metric_optimization_supported_metric.VendorMetricOptimizationSupportedMetric],
        Field(
            description="Vendor-defined metrics this product can steer delivery toward. Each entry pairs a vendor identity (BrandRef anchored on the vendor's `brand.json` `agents[type='measurement']`) with a `metric_id` from that vendor's published `measurement.metrics[]` catalog, plus the target kinds the seller supports for the pair. Semantic uniqueness key is `(vendor.domain, vendor.brand_id, metric_id)`; sellers MUST de-duplicate before publication. JSON Schema `uniqueItems` blocks exact-object duplicates; semantic deduplication on the BrandRef-domain key is a seller obligation."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var supported_metrics : list[VendorMetricOptimizationSupportedMetric]

Inherited members

class VendorMetricOptimizationSupportedMetric (**data: Any)
Expand source code
class VendorMetricOptimizationSupportedMetric(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description="Vendor that defines and computes this metric. The vendor's `brand.json` is the discovery anchor for the measurement agent (entry with `type: 'measurement'` in the `agents[]` array); the metric's definition, methodology, and unit live at that agent's `get_adcp_capabilities.measurement.metrics[]` and are not duplicated inline here. Same shape as the `vendor` field on `reporting_capabilities.vendor_metrics` for symmetry across optimization and reporting capability declarations."
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(
            description="Identifier for the metric within the vendor's vocabulary (e.g., `attention_score`, `attention_seconds`, `gco2e_per_impression`, `awareness_lift`). MUST be present in the vendor's published `measurement.metrics[]` catalog."
        ),
    ]
    supported_targets: Annotated[
        list[SupportedTarget] | None,
        Field(
            description='Target kinds available for `vendor_metric` goals against this `(vendor, metric_id)` pair. Values match `target.kind` on the optimization goal. `cost_per` — target cost per metric unit (e.g., $0.05 per attention-second). `threshold_rate` — minimum per-impression value (e.g., attention_score ≥ 70). Only these target kinds are accepted — goals with unlisted target kinds will be rejected. A goal without a target implicitly maximizes the metric within budget — no declaration needed for that mode. When omitted, buyers can still set target-less vendor_metric goals.'
        ),
    ] = 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 metric_id : VendorMetricId
var model_config
var supported_targets : list[SupportedTarget] | None
var vendor : BrandReference

Inherited members

class VendorMetricValue (**data: Any)
Expand source code
class VendorMetricValue(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    vendor: Annotated[
        brand_ref.BrandReference,
        Field(
            description='Vendor that produced this value. Matches a `vendor_metrics[].vendor` declaration on the product.'
        ),
    ]
    metric_id: Annotated[
        vendor_metric_id.VendorMetricId,
        Field(
            description="Identifier for the metric within the vendor's vocabulary. Matches a `vendor_metrics[].metric_id` declaration on the product."
        ),
    ]
    value: Annotated[
        StrictFloat,
        Field(
            description="The reported value. Unit semantics are vendor-defined — see `unit` field below and the vendor's `brand.json` measurement-agent documentation."
        ),
    ]
    unit: Annotated[
        str | None,
        Field(
            description="Unit of the value. Free-form to accommodate the heterogeneity of vendor metrics (e.g., `score`, `seconds`, `persons`, `gCO2e`, `USD`, `lift_percent`). When the value is monetary, use the ISO 4217 code (e.g., `USD`, `EUR`); for non-monetary, use whatever the vendor publishes. Optional on every row — the canonical unit lives at the vendor's measurement-agent metric definition (`brand.json` `agents[type='measurement']`). When sellers populate it inline they SHOULD match the vendor's published unit; buyers MAY resolve from the vendor's measurement agent when this field is absent.",
            examples=['score', 'seconds', 'persons', 'gCO2e', 'USD', 'lift_percent', 'index'],
        ),
    ] = None
    measurable_impressions: Annotated[
        StrictFloat | None,
        Field(
            description='Number of impressions in this reporting period that the vendor was able to measure. Coverage denominator — buyers compute coverage rate as `measurable_impressions / impressions`. When absent, coverage is unspecified — buyers MUST NOT compute a coverage rate or assume full coverage. When the vendor measured zero impressions but is integrated, set to 0 explicitly. When the entry is omitted from `vendor_metric_values` entirely, the buyer infers no measurement happened (no integration). This pattern parallels `viewability.measurable_impressions` (`delivery-metrics.json#/properties/viewability`), which has handled vendor coverage in the IAS/DV/MRC ecosystem for over a decade — same convention: absence is unknown, not full. For channels where the atomic observation unit is a play or screen-second rather than an impression (DOOH, cinema, place-based), report `measurable_plays` or `measurable_play_seconds` instead — `impressions` there is itself a modelled figure (`plays × audience multiplier`), so `measurable_impressions / impressions` divides a measured count by a model output and has no interpretation.',
            ge=0.0,
        ),
    ] = None
    measurable_plays: Annotated[
        StrictFloat | None,
        Field(
            description='Number of plays (loop plays / spots aired) in this reporting period that the vendor was able to measure. Coverage denominator for channels where a play, not an impression, is the atomic observation unit — DOOH, cinema, place-based audio. Buyers compute coverage as `measurable_plays / plays` (top-level `plays` on `delivery-metrics.json`). Same absence semantics as `measurable_impressions`: absent means coverage is unspecified and buyers MUST NOT compute a rate; 0 means the vendor is integrated but measured nothing. A row SHOULD carry exactly one coverage denominator — the one matching the unit the vendor actually observes.',
            ge=0.0,
        ),
    ] = None
    measurable_play_seconds: Annotated[
        StrictFloat | None,
        Field(
            description="Play-seconds — seconds of creative playout summed across endpoints (screens, speakers, players) — in this reporting period that the vendor was able to measure. Medium-neutral on purpose: place-based audio has plays and duration but no screen. Coverage denominator when the vendor meters exposure duration rather than discrete plays. On screen networks buyers compute coverage as `measurable_play_seconds / dooh_metrics.screen_time_seconds`; on other place-based media, against the seller's reported playout seconds for the period. Same absence semantics as `measurable_impressions`.",
            ge=0.0,
        ),
    ] = None
    vendor_relationship: Annotated[
        vendor_relationship_1.VendorRelationship | None,
        Field(
            description="Optional echo of the product's `reporting_capabilities.vendor_metrics[].vendor_relationship` for this `(vendor, metric_id)`, so the delivery row is self-describing without joining back to the product (same reasoning as `viewability.vendor`). When present it MUST equal the declared value; buyers MAY resolve from the product declaration when absent. Absence on the row is *undeclared*, never `third_party`. A relationship disposition, not a trust ranking. Deliberately not a `qualifier` key: the relationship is constant across every row for a (seller, vendor) pair and does not partition rows, so it stays out of the `(vendor, metric_id, qualifier)` reconciliation join."
        ),
    ] = None
    qualifier: Annotated[
        Qualifier | None,
        Field(
            description='Optional qualifier disambiguating this row from sibling rows for the same (vendor, metric_id) — e.g., the same vendor outcome metric reported under 7-day and 30-day attribution windows. Same closed key set as `committed-metric`. When the matching `committed_metrics` entry carries a qualifier, this row MUST carry the identical qualifier so reconciliation joins on `(vendor, metric_id, qualifier)`.'
        ),
    ] = None
    breakdown: Annotated[
        dict[str, Any] | None,
        Field(
            description="Optional structured payload for vendor metrics that don't fit a single scalar — panel demographic breakouts, co-view audience composition, incremental reach + frequency + lift decompositions. Free-form; the keys and value semantics are defined by the vendor (see the vendor's `brand.json` measurement-agent docs). Buyers MUST treat this object as opaque without consulting the vendor's documentation. Vendors place any fields beyond the standard envelope (e.g., confidence intervals, panel sizes) inside this object rather than at the top level."
        ),
    ] = 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 breakdown : dict[str, typing.Any] | None
var measurable_impressions : float | None
var measurable_play_seconds : float | None
var measurable_plays : float | None
var metric_id : VendorMetricId
var model_config
var qualifier : Qualifier | None
var unit : str | None
var value : float
var vendor : BrandReference
var vendor_relationship : VendorRelationship | None

Inherited members

class VendorPricing1 (**data: Any)
Expand source code
class VendorPricing1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['cpm'] = 'cpm'
    cpm: Annotated[StrictFloat, Field(description='Cost per thousand impressions', ge=0.0)]
    currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')]
    ext: ext_1.ExtensionObject | 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 cpm : float
var currency : str
var ext : ExtensionObject | None
var model : Literal['cpm']
var model_config

Inherited members

class VendorPricing2 (**data: Any)
Expand source code
class VendorPricing2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['percent_of_media'] = 'percent_of_media'
    percent: Annotated[
        StrictFloat, Field(description='Percentage of media spend, e.g. 15 = 15%', ge=0.0, le=100.0)
    ]
    max_cpm: Annotated[
        StrictFloat | None,
        Field(
            description='Optional CPM cap. When set, the effective charge is min(percent × media_spend_per_mille, max_cpm).',
            ge=0.0,
        ),
    ] = None
    currency: Annotated[
        str,
        Field(description='ISO 4217 currency code for the resulting charge', pattern='^[A-Z]{3}$'),
    ]
    ext: ext_1.ExtensionObject | 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 currency : str
var ext : ExtensionObject | None
var max_cpm : float | None
var model : Literal['percent_of_media']
var model_config
var percent : float

Inherited members

class VendorPricing3 (**data: Any)
Expand source code
class VendorPricing3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['flat_fee'] = 'flat_fee'
    amount: Annotated[StrictFloat, Field(description='Fixed charge for the billing period', ge=0.0)]
    period: Annotated[Period, Field(description='Billing period for the flat fee.')]
    currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')]
    ext: ext_1.ExtensionObject | 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 amount : float
var currency : str
var ext : ExtensionObject | None
var model : Literal['flat_fee']
var model_config
var period : Period

Inherited members

class VendorPricing4 (**data: Any)
Expand source code
class VendorPricing4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['per_unit'] = 'per_unit'
    unit: Annotated[
        str,
        Field(
            description="What is counted — e.g. 'format', 'image', 'token', 'variant', 'render', 'evaluation'."
        ),
    ]
    unit_price: Annotated[StrictFloat, Field(description='Cost per one unit', ge=0.0)]
    currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')]
    ext: ext_1.ExtensionObject | 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 currency : str
var ext : ExtensionObject | None
var model : Literal['per_unit']
var model_config
var unit : str
var unit_price : float

Inherited members

class VendorPricing5 (**data: Any)
Expand source code
class VendorPricing5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['custom'] = 'custom'
    description: Annotated[
        str,
        Field(
            description='Human-readable description of the custom pricing model. Buyers display this to the operator when requesting approval.',
            min_length=1,
        ),
    ]
    metadata: Annotated[
        Metadata,
        Field(
            description="Structured parameters for the custom model. Keys follow lowercase_snake_case. Values may be primitives, arrays, or nested objects. Must be sufficient for a human to understand the pricing basis and for a downstream system to reconstruct the charge. Vendors SHOULD include a `summary_for_operator` string (one or two sentences, suitable for display in a buyer's operator-review UI) so reviewers across vendors see a consistent prompt. Required operator-review fields (approver role, dollar threshold for automatic approval, escalation contact) MAY be surfaced via additional keys the buyer's review surface recognizes."
        ),
    ]
    currency: Annotated[
        str | None,
        Field(
            description='ISO 4217 currency code. Present when the pricing resolves to a monetary charge in a specific currency.',
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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 currency : str | None
var description : str
var ext : ExtensionObject | None
var metadata : Metadata
var model : Literal['custom']
var model_config

Inherited members

class VendorPricingOption1 (**data: Any)
Expand source code
class VendorPricingOption1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['cpm'] = 'cpm'
    cpm: Annotated[StrictFloat, Field(description='Cost per thousand impressions', ge=0.0)]
    currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')]
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var cpm : float
var currency : str
var ext : ExtensionObject | None
var model : Literal['cpm']
var model_config

Inherited members

class VendorPricingOption10 (**data: Any)
Expand source code
class VendorPricingOption10(VendorPricingOption4, VendorPricingOption6):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class VendorPricingOption11 (**data: Any)
Expand source code
class VendorPricingOption11(VendorPricingOption5, VendorPricingOption6):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class VendorPricingOption2 (**data: Any)
Expand source code
class VendorPricingOption2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['percent_of_media'] = 'percent_of_media'
    percent: Annotated[
        StrictFloat, Field(description='Percentage of media spend, e.g. 15 = 15%', ge=0.0, le=100.0)
    ]
    max_cpm: Annotated[
        StrictFloat | None,
        Field(
            description='Optional CPM cap. When set, the effective charge is min(percent × media_spend_per_mille, max_cpm).',
            ge=0.0,
        ),
    ] = None
    currency: Annotated[
        str,
        Field(description='ISO 4217 currency code for the resulting charge', pattern='^[A-Z]{3}$'),
    ]
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var currency : str
var ext : ExtensionObject | None
var max_cpm : float | None
var model : Literal['percent_of_media']
var model_config
var percent : float

Inherited members

class VendorPricingOption3 (**data: Any)
Expand source code
class VendorPricingOption3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['flat_fee'] = 'flat_fee'
    amount: Annotated[StrictFloat, Field(description='Fixed charge for the billing period', ge=0.0)]
    period: Annotated[Period, Field(description='Billing period for the flat fee.')]
    currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')]
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var amount : float
var currency : str
var ext : ExtensionObject | None
var model : Literal['flat_fee']
var model_config
var period : Period

Inherited members

class VendorPricingOption4 (**data: Any)
Expand source code
class VendorPricingOption4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['per_unit'] = 'per_unit'
    unit: Annotated[
        str,
        Field(
            description="What is counted — e.g. 'format', 'image', 'token', 'variant', 'render', 'evaluation'."
        ),
    ]
    unit_price: Annotated[StrictFloat, Field(description='Cost per one unit', ge=0.0)]
    currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')]
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var currency : str
var ext : ExtensionObject | None
var model : Literal['per_unit']
var model_config
var unit : str
var unit_price : float

Inherited members

class VendorPricingOption5 (**data: Any)
Expand source code
class VendorPricingOption5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Literal['custom'] = 'custom'
    description: Annotated[
        str,
        Field(
            description='Human-readable description of the custom pricing model. Buyers display this to the operator when requesting approval.',
            min_length=1,
        ),
    ]
    metadata: Annotated[
        Metadata,
        Field(
            description="Structured parameters for the custom model. Keys follow lowercase_snake_case. Values may be primitives, arrays, or nested objects. Must be sufficient for a human to understand the pricing basis and for a downstream system to reconstruct the charge. Vendors SHOULD include a `summary_for_operator` string (one or two sentences, suitable for display in a buyer's operator-review UI) so reviewers across vendors see a consistent prompt. Required operator-review fields (approver role, dollar threshold for automatic approval, escalation contact) MAY be surfaced via additional keys the buyer's review surface recognizes."
        ),
    ]
    currency: Annotated[
        str | None,
        Field(
            description='ISO 4217 currency code. Present when the pricing resolves to a monetary charge in a specific currency.',
            pattern='^[A-Z]{3}$',
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var currency : str | None
var description : str
var ext : ExtensionObject | None
var metadata : Metadata
var model : Literal['custom']
var model_config

Inherited members

class VendorPricingOption6 (**data: Any)
Expand source code
class VendorPricingOption6(AdCPBaseModel):
    pricing_option_id: Annotated[
        str,
        Field(
            description='Opaque identifier for this pricing option, unique within the vendor agent. Pass this in report_usage to identify which pricing option was applied.'
        ),
    ]
    applies_to_output_format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format pricing scope. Use applies_to_output_capability_ids.',
            min_length=1,
        ),
    ] = None
    applies_to_output_capability_ids: Annotated[
        list[AppliesToOutputCapabilityId] | None,
        Field(
            description='Creative transformers only: scopes this pricing option to canonical output capabilities advertised in creative.supported_formats[].capability_id. When absent, the option is the default for any output. A build targeting an output that matches no scoped option and has no unscoped default is rejected with UNPRICEABLE_OUTPUT.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var applies_to_output_capability_ids : list[AppliesToOutputCapabilityId] | None
var applies_to_output_format_ids : list[FormatReferenceStructuredObject] | None
var model_config
var pricing_option_id : str

Inherited members

class VendorPricingOption7 (**data: Any)
Expand source code
class VendorPricingOption7(VendorPricingOption1, VendorPricingOption6):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class VendorPricingOption8 (**data: Any)
Expand source code
class VendorPricingOption8(VendorPricingOption2, VendorPricingOption6):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class VendorPricingOption9 (**data: Any)
Expand source code
class VendorPricingOption9(VendorPricingOption3, VendorPricingOption6):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class VenueBreakdownItem (**data: Any)
Expand source code
class VenueBreakdownItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    venue_id: Annotated[str, Field(description='Venue identifier')]
    venue_name: Annotated[str | None, Field(description='Human-readable venue name')] = None
    venue_type: Annotated[
        str | None,
        Field(description="Venue type (e.g., 'airport', 'transit', 'retail', 'billboard')"),
    ] = None
    impressions: Annotated[
        SchemaInt, Field(description='Impressions delivered at this venue', ge=0)
    ]
    loop_plays: Annotated[SchemaInt | None, Field(description='Loop plays at this venue', ge=0)] = (
        None
    )
    screens_used: Annotated[
        SchemaInt | None, Field(description='Number of screens used at this venue', 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

Class variables

var impressions : int
var loop_plays : int | None
var model_config
var screens_used : int | None
var venue_id : str
var venue_name : str | None
var venue_type : str | None

Inherited members

class VerificationPath (*args, **kwds)
Expand source code
class VerificationPath(StrEnum):
    producer = 'producer'
    representative_consumer = 'representative_consumer'
    destination = 'destination'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var destination
var producer
var representative_consumer
class VerificationTokenGradingProfile (*args, **kwds)
Expand source code
class VerificationTokenGradingProfile(StrEnum):
    legacy = 'legacy'
    spec = 'spec'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var legacy
var spec
class VerificationTokenMode (*args, **kwds)
Expand source code
class VerificationTokenMode(StrEnum):
    spec = 'spec'
    live = 'live'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var live
var spec
class VerifiedAttestationDigest (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class VerifiedAttestationDigest(ScalarStr):
    __slots__ = ()
    _constraints = {'pattern': '^sha256:[a-f0-9]{64}$'}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class VerifyAgent1 (**data: Any)
Expand source code
class VerifyAgent1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[
        AnyUrl,
        Field(
            description="URL of the governance agent the buyer represents was used to apply/detect this watermark. MUST use the `https://` scheme and MUST appear in the seller's `creative_policy.accepted_verifiers[].agent_url` list (canonicalized per /docs/reference/url-canonicalization: lowercase scheme and host, strip default port, normalize path dot-segments). Sellers MUST NOT call this URL until the canonicalized match is confirmed."
        ),
    ]
    feature_id: Annotated[
        str | None,
        Field(
            description="Optional `feature_id` the buyer represents the seller should request via `get_creative_features` (e.g., `imatag.watermark_detected`). SHOULD match the `feature_id` declared on the matching `accepted_verifiers[]` entry, or be omitted to defer the selector to the seller. When the seller's entry pins a `feature_id`, that value wins; when neither side pins, the seller selects from the agent's `governance.creative_features` catalog."
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var feature_id : str | None
var model_config

Inherited members

class VerifyAgent18 (**data: Any)
Expand source code
class VerifyAgent18(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[
        AnyUrl,
        Field(
            description="URL of the governance agent the buyer represents was used to apply/detect this watermark. MUST use the `https://` scheme and MUST appear in the seller's `creative_policy.accepted_verifiers[].agent_url` list (canonicalized per /docs/reference/url-canonicalization: lowercase scheme and host, strip default port, normalize path dot-segments). Sellers MUST NOT call this URL until the canonicalized match is confirmed."
        ),
    ]
    feature_id: Annotated[
        str | None,
        Field(
            description="Optional `feature_id` the buyer represents the seller should request via `get_creative_features` (e.g., `imatag.watermark_detected`). SHOULD match the `feature_id` declared on the matching `accepted_verifiers[]` entry, or be omitted to defer the selector to the seller. When the seller's entry pins a `feature_id`, that value wins; when neither side pins, the seller selects from the agent's `governance.creative_features` catalog."
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var feature_id : str | None
var model_config

Inherited members

class VideoAssetRequirements (**data: Any)
Expand source code
class VideoAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    min_width: Annotated[SchemaInt | None, Field(description='Minimum width in pixels', ge=1)] = (
        None
    )
    max_width: Annotated[SchemaInt | None, Field(description='Maximum width in pixels', ge=1)] = (
        None
    )
    min_height: Annotated[SchemaInt | None, Field(description='Minimum height in pixels', ge=1)] = (
        None
    )
    max_height: Annotated[SchemaInt | None, Field(description='Maximum height in pixels', ge=1)] = (
        None
    )
    aspect_ratio: Annotated[
        str | None,
        Field(description="Required aspect ratio (e.g., '16:9', '9:16')", pattern='^\\d+:\\d+$'),
    ] = None
    min_duration_ms: Annotated[
        SchemaInt | None, Field(description='Minimum duration in milliseconds', ge=1)
    ] = None
    max_duration_ms: Annotated[
        SchemaInt | None, Field(description='Maximum duration in milliseconds', ge=1)
    ] = None
    containers: Annotated[
        list[Container] | None, Field(description='Accepted video container formats')
    ] = None
    codecs: Annotated[list[Codec] | None, Field(description='Accepted video codecs')] = None
    max_file_size_kb: Annotated[
        SchemaInt | None,
        Field(description='Maximum file size, where 1 KB is exactly 1,000 bytes', ge=1),
    ] = None
    min_bitrate_kbps: Annotated[
        SchemaInt | None, Field(description='Minimum video bitrate in kilobits per second', ge=1)
    ] = None
    max_bitrate_kbps: Annotated[
        SchemaInt | None, Field(description='Maximum video bitrate in kilobits per second', ge=1)
    ] = None
    frame_rates: Annotated[
        list[FrameRate] | None,
        Field(description='Accepted frame rates in frames per second (e.g., [24, 30, 60])'),
    ] = None
    audio_required: Annotated[
        StrictBool | None, Field(description='Whether the video must include an audio track')
    ] = None
    frame_rate_type: Annotated[
        frame_rate_type_1.FrameRateType | None,
        Field(
            description='Required frame rate type. Broadcast and SSAI require constant frame rate for seamless splicing.'
        ),
    ] = None
    scan_type: Annotated[
        scan_type_1.ScanType | None,
        Field(description='Required scan type. Modern delivery requires progressive scan.'),
    ] = None
    gop_type: Annotated[
        gop_type_1.GopType | None,
        Field(
            description='Required GOP structure. SSAI and broadcast require closed GOPs for clean splice points.'
        ),
    ] = None
    min_gop_interval_seconds: Annotated[
        StrictFloat | None, Field(description='Minimum keyframe interval in seconds', ge=0.0)
    ] = None
    max_gop_interval_seconds: Annotated[
        StrictFloat | None,
        Field(
            description='Maximum keyframe interval in seconds. SSAI typically requires 1-2 second intervals.',
            ge=0.0,
        ),
    ] = None
    moov_atom_position: Annotated[
        moov_atom_position_1.MoovAtomPosition | None,
        Field(
            description="Required moov atom position in MP4 container. 'start' enables progressive download without buffering the entire file."
        ),
    ] = None
    audio_codecs: Annotated[
        list[AudioCodec] | None,
        Field(description="Accepted audio codecs (e.g., ['aac', 'pcm', 'ac3'])"),
    ] = None
    audio_sample_rates: Annotated[
        list[AudioSampleRate] | None,
        Field(description='Accepted audio sample rates in Hz (e.g., [44100, 48000])'),
    ] = None
    audio_channels: Annotated[
        list[audio_channel_layout.AudioChannelLayout] | None,
        Field(description='Accepted audio channel configurations'),
    ] = None
    loudness_lufs: Annotated[
        StrictFloat | None,
        Field(
            description='Target integrated loudness in LUFS (e.g., -24 for broadcast, -16 for streaming)'
        ),
    ] = None
    loudness_tolerance_db: Annotated[
        StrictFloat | None,
        Field(
            description='Acceptable deviation from loudness_lufs target in dB (e.g., 2 means -22 to -26 LUFS for a -24 target)',
            ge=0.0,
        ),
    ] = None
    true_peak_dbfs: Annotated[
        StrictFloat | None,
        Field(description='Maximum true peak level in dBFS (e.g., -2 for broadcast)'),
    ] = 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 aspect_ratio : str | None
var audio_channels : list[AudioChannelLayout] | None
var audio_codecs : list[AudioCodec] | None
var audio_required : bool | None
var audio_sample_rates : list[AudioSampleRate] | None
var codecs : list[Codec] | None
var containers : list[Container] | None
var frame_rate_type : FrameRateType | None
var frame_rates : list[FrameRate] | None
var gop_type : GopType | None
var loudness_lufs : float | None
var loudness_tolerance_db : float | None
var max_bitrate_kbps : int | None
var max_duration_ms : int | None
var max_file_size_kb : int | None
var max_gop_interval_seconds : float | None
var max_height : int | None
var max_width : int | None
var min_bitrate_kbps : int | None
var min_duration_ms : int | None
var min_gop_interval_seconds : float | None
var min_height : int | None
var min_width : int | None
var model_config
var moov_atom_position : MoovAtomPosition | None
var scan_type : ScanType | None
var true_peak_dbfs : float | None

Inherited members

class Viewability1 (**data: Any)
Expand source code
class Viewability1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description="Vendor that produced these viewability values. Optional but RECOMMENDED so the row is self-describing — buyer agents reading delivery in isolation can attribute the numbers without joining back to `package.committed_metrics` or `package.performance_standards`. The vendor's `brand.json` `agents[type='measurement']` is the discovery anchor; the metric definitions live on the agent's `get_adcp_capabilities.measurement.metrics[]` block. Same shape as `vendor_metric_value.vendor` for symmetry across vendor-attested surfaces."
        ),
    ] = None
    measurable_impressions: Annotated[
        StrictFloat | None,
        Field(
            description='Impressions where viewability could be measured. Excludes environments without measurement capability (e.g., non-Intersection Observer browsers, certain app environments). Coverage denominator for `viewable_rate`, `viewed_seconds`, and both viewed-seconds distributions — every duration statistic is computed over this same measurable population.',
            ge=0.0,
        ),
    ] = None
    viewable_impressions: Annotated[
        StrictFloat | None,
        Field(
            description='Impressions that met the viewability threshold defined by the measurement standard.',
            ge=0.0,
        ),
    ] = None
    viewable_rate: Annotated[
        StrictFloat | None,
        Field(
            description='Viewable impression rate (viewable_impressions / measurable_impressions). Range 0.0 to 1.0.',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    viewed_seconds: Annotated[
        StrictFloat | None,
        Field(
            description="Average in-view duration per measurable impression, in seconds. Reporting-side counterpart to the `viewed_seconds` optimization metric in `optimization-goal.json`. Computed over `measurable_impressions`, not total impressions — the same denominator as `viewable_rate`. The viewability `standard` governs the threshold (e.g., MRC's 50% pixels for 1s display / 2s video) that defines when an impression is in view and therefore when the clock is running. Sellers reporting against a `viewed_seconds` optimization goal MUST populate this field.",
            ge=0.0,
        ),
    ] = None
    viewed_seconds_percentiles: Annotated[
        ViewedSecondsPercentiles | None,
        Field(
            description='Percentile summary of the per-impression in-view durations whose arithmetic mean is reported in `viewed_seconds`. This object MUST use the same reporting row, measurement vendor, viewability `standard`, and `measurable_impressions` population as `viewed_seconds`; sellers MUST omit it when `measurable_impressions` is zero. Percentiles use the nearest-rank definition: sort the N observed durations in ascending order and select rank `ceil(p × N)` (one-based) for percentile p. Values MUST be non-decreasing from p25 through p95. The structured metric identity `viewed_seconds_percentiles` makes this optional surface discoverable and requestable; it is not sortable and the nested object remains the canonical carrier.'
        ),
    ] = None
    viewed_seconds_histogram: Annotated[
        list[ViewedSecondsHistogramItem] | None,
        Field(
            description='Bucketed counts of the per-impression in-view durations whose arithmetic mean is reported in `viewed_seconds`. Buckets MUST be ordered by ascending lower bound, MUST NOT overlap, and MUST partition every impression in the same `measurable_impressions` population exactly once; therefore the sum of `impressions` MUST equal `measurable_impressions`. Buckets need not be contiguous: a gap between consecutive bucket boundaries is permitted when no impressions fall within that range — the sum constraint enforces this implicitly, and validators MUST NOT independently require contiguity. Each bucket is half-open `[lower_bound_seconds, upper_bound_seconds)`; only the final bucket MAY omit `upper_bound_seconds`, representing an unbounded upper range. Sellers choose boundaries, but buyers MUST combine histograms only when the complete boundary sequence, measurement vendor, and viewability `standard` match. The structured metric identity `viewed_seconds_histogram` makes this optional surface discoverable and requestable; it is not sortable and this nested array remains the canonical carrier.',
            min_length=1,
        ),
    ] = None
    standard: Annotated[
        viewability_standard.ViewabilityStandard | None,
        Field(
            description='Viewability measurement standard applied to these metrics. Governs the in-view threshold for `viewable_rate`, `viewed_seconds`, and both viewed-seconds distributions.'
        ),
    ] = 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 measurable_impressions : float | None
var model_config
var standard : ViewabilityStandard | None
var vendor : BrandReference | None
var viewable_impressions : float | None
var viewable_rate : float | None
var viewed_seconds : float | None
var viewed_seconds_histogram : list[ViewedSecondsHistogramItem] | None
var viewed_seconds_percentiles : ViewedSecondsPercentiles | None

Inherited members

class ViewableRate (**data: Any)
Expand source code
class ViewableRate(CoverageRate):
    pass

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class ViewedSecondsHistogramItem (**data: Any)
Expand source code
class ViewedSecondsHistogramItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    lower_bound_seconds: Annotated[
        StrictFloat,
        Field(description='Inclusive lower bound of this duration bucket, in seconds.', ge=0.0),
    ]
    upper_bound_seconds: Annotated[
        StrictFloat | None,
        Field(
            description='Exclusive upper bound of this duration bucket, in seconds. MUST be greater than `lower_bound_seconds`. Omit only on the final bucket to represent an unbounded upper range.',
            ge=0.0,
        ),
    ] = None
    impressions: Annotated[
        SchemaInt,
        Field(
            description='Number of measurable impressions whose in-view duration falls in this bucket.',
            ge=0,
        ),
    ]

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 impressions : int
var lower_bound_seconds : float
var model_config
var upper_bound_seconds : float | None

Inherited members

class ViewedSecondsPercentiles (**data: Any)
Expand source code
class ViewedSecondsPercentiles(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    p25: Annotated[
        StrictFloat, Field(description='25th-percentile in-view duration in seconds.', ge=0.0)
    ]
    p50: Annotated[
        StrictFloat,
        Field(description='Median (50th-percentile) in-view duration in seconds.', ge=0.0),
    ]
    p75: Annotated[
        StrictFloat, Field(description='75th-percentile in-view duration in seconds.', ge=0.0)
    ]
    p90: Annotated[
        StrictFloat, Field(description='90th-percentile in-view duration in seconds.', ge=0.0)
    ]
    p95: Annotated[
        StrictFloat, Field(description='95th-percentile in-view duration in seconds.', ge=0.0)
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var p25 : float
var p50 : float
var p75 : float
var p90 : float
var p95 : float

Inherited members

class Visual (**data: Any)
Expand source code
class Visual(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    url: Annotated[
        AnyUrl | None,
        Field(
            description='URL to a theme-neutral overlay graphic (SVG or PNG). Use when a single file works for all backgrounds, e.g. an SVG using CSS custom properties or currentColor.'
        ),
    ] = None
    light: Annotated[
        AnyUrl | None,
        Field(
            description='URL to the overlay graphic for use on light/bright backgrounds (SVG or PNG)'
        ),
    ] = None
    dark: Annotated[
        AnyUrl | None,
        Field(description='URL to the overlay graphic for use on dark backgrounds (SVG or PNG)'),
    ] = 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 dark : pydantic.networks.AnyUrl | None
var light : pydantic.networks.AnyUrl | None
var model_config
var url : pydantic.networks.AnyUrl | None

Inherited members

class VoiceSynthesisRefItem (**data: Any)
Expand source code
class VoiceSynthesisRefItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    brand_agent: Annotated[
        BrandAgent,
        Field(description='Brand agent that exposed the referenced voice_synthesis entry.'),
    ]
    voice_id: Annotated[str, Field(description='voice_synthesis.voice_id from the brand agent.')]
    rights_id: Annotated[
        str | None,
        Field(
            description='Optional rights offering or buyer-specific grant identifier associated with this provisioned voice. Brand-side voice_synthesis uses rights_offering_id for the configuration-time offering anchor. This transformer field may carry that offering ID or a grant ID after provisioning; it remains provenance metadata only, not a build_creative rights token.'
        ),
    ] = 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 brand_agent : BrandAgent
var model_config
var rights_id : str | None
var voice_id : str

Inherited members

class Warning (**data: Any)
Expand source code
class Warning(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    code: warning_code.WarningCode
    message: Annotated[
        str,
        Field(
            description='Short human-readable explanation. Treat as untrusted seller text and do not require buyers to parse it for routing.',
            max_length=2000,
            min_length=1,
        ),
    ]
    affected_resource: Annotated[
        warning_resource.WarningAffectedResource,
        Field(
            description='Resource or relationship affected by this warning. Required so multi-package and multi-creative responses remain machine-joinable.'
        ),
    ]
    details: Annotated[
        dict[str, Any] | None,
        Field(
            description='Optional seller-specific structured diagnostics. AdCP 3.2 defines interoperability through code and affected_resource only; buyers MUST NOT require portable keys inside details. Seller extensions that are not direct diagnostics belong in ext.'
        ),
    ] = None
    ext: ext_1.ExtensionObject | 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

Subclasses

Class variables

var affected_resource : WarningAffectedResource
var code : WarningCode
var details : dict[str, typing.Any] | None
var ext : ExtensionObject | None
var message : str
var model_config

Inherited members

class WarningAffectedResource (**data: Any)
Expand source code
class WarningAffectedResource(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    resource_type: ResourceType
    media_buy_id: str | None = None
    package_id: str | None = None
    creative_id: str | 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 creative_id : str | None
var media_buy_id : str | None
var model_config
var package_id : str | None
var resource_type : ResourceType

Inherited members

class WatermarkMediaType (*args, **kwds)
Expand source code
class WatermarkMediaType(StrEnum):
    audio = 'audio'
    image = 'image'
    video = 'video'
    text = 'text'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var audio
var image
var text
var video
class WebhookActivityRecord (**data: Any)
Expand source code
class WebhookActivityRecord(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Equals the `idempotency_key` carried in the webhook payload itself (see docs/building/by-layer/L3/webhooks.mdx § Dedup by `idempotency_key`). Stable across retry attempts of the same logical fire — retries with `attempt` > 1 reuse this key. Buyers correlate this surface with their own endpoint logs via this exact field; the spec deliberately reuses the payload key rather than minting a parallel `delivery_id` so callers do not need a join table. Format is sender-defined; callers MUST treat as opaque.'
        ),
    ]
    notification_id: Annotated[
        str | None,
        Field(
            description='Optional event-layer identifier copied verbatim from the webhook payload. For fires whose payload carries `notification_id`, sellers SHOULD populate this field on newly recorded attempts and, when populated, MUST copy the payload value without transformation. The field remains optional in AdCP 3.2 so sellers can return retained activity records created before they persisted event identity. Point-in-time delivery-report fires do not define `notification_id` and omit this field. Re-emissions of the same logical event have different `idempotency_key` values but reuse `notification_id`, allowing buyers to distinguish a re-emission from a transport retry. Callers MUST treat the value as opaque.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    subscriber_id: Annotated[
        str | None,
        Field(
            description='Identifies which registered webhook subscriber received this fire. **Required on records from account-anchored notification channels** (`notification_configs[]` registered via `sync_accounts`) — every subscriber has a `subscriber_id` at registration time, the seller MUST echo it on every fire and every activity record. **Optional on records from per-resource push channels** (`push_notification_config` on a media buy or task) — the calling principal is unambiguous in single-subscriber configurations and the field MAY be omitted; sellers MUST populate it once `reporting_webhook` adopts multi-subscriber (per #3009 in AdCP 4.0). Buyers MUST NOT use absence as a signal that no other subscribers exist; that information is not exposed by this surface.'
        ),
    ] = None
    fired_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller initiated the HTTP request for this attempt.'
        ),
    ]
    completed_at: Annotated[
        AwareDatetime | None,
        Field(
            description="ISO 8601 timestamp when the seller observed the response (or terminal timeout / connection error — for `timeout` and `connection_error` outcomes, `completed_at` is set to the moment the seller declared the attempt terminal). Explicitly `null` when the attempt is still in flight or queued for retry (status `pending`); MUST be set as `null` rather than omitted so callers can distinguish 'still in flight' from 'field missing'."
        ),
    ] = None
    notification_type: Annotated[
        notification_type_1.NotificationType,
        Field(
            description='Notification type carried by this fire, verbatim from the webhook payload. Includes delivery-report types (`scheduled`, `final`, `delayed`, `adjusted`, `window_update`), health notifications (`impairment`), and account-anchored indicator or creative-assignment invalidations from the shared registry. All share the same persistent-channel webhook contract and the same buyer-side debug need.'
        ),
    ]
    sequence_number: Annotated[
        SchemaInt | None,
        Field(
            description='Sequence number from the webhook payload. Surfaced here so the buyer can spot stale-sequence drops and gaps without correlating against their own endpoint log. Absent for notification types that do not carry a sequence number.',
            ge=0,
        ),
    ] = None
    attempt: Annotated[
        SchemaInt,
        Field(
            description='1-indexed retry counter for this logical fire. Initial fire is attempt=1; retries increment. Sellers MUST emit one record per attempt, so a successful first-attempt fire appears as a single record with `attempt: 1` and a 3-attempt retry trail appears as three records sharing `idempotency_key`.',
            ge=1,
        ),
    ]
    status: Annotated[
        Status,
        Field(
            description="Outcome of this attempt. `success` — response received with 2xx (`http_status_code` populated). `failed` — response received with non-2xx (`http_status_code` populated). `timeout` — no response within the seller's configured timeout (`http_status_code` null). `connection_error` — DNS / TLS / socket failure before any HTTP response (`http_status_code` null). `pending` — attempt is in flight or queued for retry (`completed_at` null, `http_status_code` null). The `timeout` / `connection_error` split is intentional and operationally distinct: `timeout` typically signals a slow / overloaded buyer endpoint, `connection_error` typically signals it is unreachable or misconfigured."
        ),
    ]
    url: Annotated[
        AnyUrl,
        Field(
            description='Target URL for this fire. Query string and fragment MUST be stripped before surfacing — buyers commonly stash bearer tokens in the query string and sellers MUST NOT echo those back through this debug surface. Sellers SHOULD additionally redact path segments matching obvious secret patterns (e.g., a path segment that is high-entropy random material or matches a UUID / token format). Buyers matching this against their own configured URL should compare by origin + path; query strings will not match and that mismatch is expected.'
        ),
    ]
    http_status_code: Annotated[
        SchemaInt | None,
        Field(
            description="HTTP status code returned by the buyer's endpoint. Explicitly `null` when no HTTP response was received (status `timeout`, `connection_error`, or `pending`); MUST be set as `null` rather than omitted.",
            ge=100,
            le=599,
        ),
    ] = None
    response_time_ms: Annotated[
        SchemaInt | None,
        Field(
            description='Wall-clock latency between request send and response receipt, in milliseconds. Explicitly `null` when the attempt did not complete (`timeout`, `connection_error`, `pending`); MUST be set as `null` rather than omitted.',
            ge=0,
        ),
    ] = None
    payload_size_bytes: Annotated[
        SchemaInt | None,
        Field(
            description="Size of the request body the seller sent, in bytes. Useful for diagnosing oversized-payload rejections from the buyer's gateway.",
            ge=0,
        ),
    ] = None
    error_message: Annotated[
        str | None,
        Field(
            description='Short human-readable server-side classification of why this attempt did not succeed (e.g., `connection refused`, `TLS handshake timeout`, `HTTP 503 Service Unavailable`). Explicitly `null` for `success` (MUST be set as `null` rather than omitted). Sellers MUST NOT include request headers, request body content, or response body content in this field — payload surfacing is reserved for a future `include_webhook_payloads` extension and is subject to stricter access controls. Sellers SHOULD also avoid including buyer-endpoint internal hostnames, stack traces, or other implementation detail leaked by the response — keep it a stable classification string.',
            max_length=500,
        ),
    ] = None
    ext: Annotated[
        ext_1.ExtensionObject | None,
        Field(
            description='Resource-specific extension slot. Adopters MAY surface a resource-specific cross-reference (e.g., `creative_id` on a creative-lifecycle record, `media_buy_id` on a record nested inside an account-level read) under `ext` rather than adding top-level fields — the canonical record shape stays uniform across resources and the `ext` envelope absorbs per-resource needs. Top-level extensions are not permitted (`additionalProperties: false`).'
        ),
    ] = 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 attempt : int
var completed_at : pydantic.types.AwareDatetime | None
var error_message : str | None
var ext : ExtensionObject | None
var fired_at : pydantic.types.AwareDatetime
var http_status_code : int | None
var idempotency_key : str
var model_config
var notification_id : str | None
var notification_type : NotificationType
var payload_size_bytes : int | None
var response_time_ms : int | None
var sequence_number : int | None
var status : Status
var subscriber_id : str | None
var url : pydantic.networks.AnyUrl

Inherited members

class WebhookAssetRequirements (**data: Any)
Expand source code
class WebhookAssetRequirements(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    methods: Annotated[list[Method] | None, Field(description='Allowed HTTP methods')] = 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 methods : list[Method] | None
var model_config

Inherited members

class WebhookChallenge (**data: Any)
Expand source code
class WebhookChallenge(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    type: Annotated[
        Literal['webhook.challenge'],
        Field(description='Discriminator for endpoint proof-of-control challenges.'),
    ] = 'webhook.challenge'
    challenge: Annotated[
        str,
        Field(
            description='Opaque, cryptographically random value that the receiver must echo in the response body. Recommended encoding: base64url without padding.',
            max_length=255,
            min_length=32,
            pattern='^[A-Za-z0-9_.:-]{32,255}$',
        ),
    ]
    account_id: Annotated[
        str,
        Field(
            description='Seller account identifier for the account whose notification_configs[] entry is being challenged.'
        ),
    ]
    subscriber_id: Annotated[
        str,
        Field(
            description='Buyer-supplied subscriber identifier from the notification_configs[] entry being challenged.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    seller_agent_url: Annotated[
        AnyUrl,
        Field(
            description='Exact seller agent URL whose RFC 9421 webhook profile key signs this challenge and that will send subsequent webhooks.'
        ),
    ]
    delivery_auth: Annotated[
        DeliveryAuth,
        Field(
            description='Authentication/signing mode the seller will use for subsequent webhooks delivered to this notification config.'
        ),
    ]
    event_types: Annotated[
        list[notification_type.NotificationType],
        Field(
            description='Normalized notification types requested by the subscriber at the time of the challenge. Part of the endpoint proof scope; changing event_types[] requires a fresh challenge before the new set can become active.',
            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 account_id : str
var challenge : str
var delivery_auth : DeliveryAuth
var event_types : list[NotificationType]
var model_config
var seller_agent_url : pydantic.networks.AnyUrl
var subscriber_id : str
var type : Literal['webhook.challenge']

Inherited members

class WebhookChallengeResponse (**data: Any)
Expand source code
class WebhookChallengeResponse(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    challenge: Annotated[
        str | None,
        Field(
            description='Echo of the challenge value supplied by the seller.',
            max_length=255,
            min_length=32,
            pattern='^[A-Za-z0-9_.:-]{32,255}$',
        ),
    ] = None
    token: Annotated[
        str | None,
        Field(
            description='Backward-compatible alias for `challenge`. Receivers SHOULD prefer `challenge`; sellers MUST accept either field.',
            max_length=255,
            min_length=32,
            pattern='^[A-Za-z0-9_.:-]{32,255}$',
        ),
    ] = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> WebhookChallengeResponse:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('challenge',), ('token',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'WebhookChallengeResponse requires at least one of these field groups: challenge | token'
        )

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 challenge : str | None
var model_config
var token : str | None

Inherited members

class WebhookResponseType (*args, **kwds)
Expand source code
class WebhookResponseType(StrEnum):
    html = 'html'
    json = 'json'
    xml = 'xml'
    javascript = 'javascript'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var html
var javascript
var json
var xml
class WebhookSecurityMethod (*args, **kwds)
Expand source code
class WebhookSecurityMethod(StrEnum):
    hmac_sha256 = 'hmac_sha256'
    api_key = 'api_key'
    none = 'none'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var api_key
var hmac_sha256
var none
class WebhookSigningAlgorithm (*args, **kwds)
Expand source code
class WebhookSigningAlgorithm(StrEnum):
    ed25519 = 'ed25519'
    ecdsa_p256_sha256 = 'ecdsa-p256-sha256'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var ecdsa_p256_sha256
var ed25519
class WholesaleFeedEvent1 (**data: Any)
Expand source code
class WholesaleFeedEvent1(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['product.created'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'product.created'
    entity_type: Annotated[
        Literal['product'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'product'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload17,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.product']
var event_id : uuid.UUID
var event_type : Literal['product.created']
var model_config
var payload : Payload17

Inherited members

class WholesaleFeedEvent2 (**data: Any)
Expand source code
class WholesaleFeedEvent2(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['product.updated'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'product.updated'
    entity_type: Annotated[
        Literal['product'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'product'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload18,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.product']
var event_id : uuid.UUID
var event_type : Literal['product.updated']
var model_config
var payload : Payload18

Inherited members

class WholesaleFeedEvent3 (**data: Any)
Expand source code
class WholesaleFeedEvent3(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['product.priced'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'product.priced'
    entity_type: Annotated[
        Literal['product'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'product'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.product']
var event_id : uuid.UUID
var event_type : Literal['product.priced']
var model_config
var payload : Payload

Inherited members

class WholesaleFeedEvent4 (**data: Any)
Expand source code
class WholesaleFeedEvent4(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['product.removed'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'product.removed'
    entity_type: Annotated[
        Literal['product'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'product'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload20,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['adcp.types.domains.core.product']
var event_id : uuid.UUID
var event_type : Literal['product.removed']
var model_config
var payload : Payload20

Inherited members

class WholesaleFeedEvent5 (**data: Any)
Expand source code
class WholesaleFeedEvent5(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['signal.created'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'signal.created'
    entity_type: Annotated[
        Literal['signal'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'signal'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload21,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['signal']
var event_id : uuid.UUID
var event_type : Literal['signal.created']
var model_config
var payload : Payload21

Inherited members

class WholesaleFeedEvent6 (**data: Any)
Expand source code
class WholesaleFeedEvent6(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['signal.updated'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'signal.updated'
    entity_type: Annotated[
        Literal['signal'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'signal'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload22,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['signal']
var event_id : uuid.UUID
var event_type : Literal['signal.updated']
var model_config
var payload : Payload22

Inherited members

class WholesaleFeedEvent7 (**data: Any)
Expand source code
class WholesaleFeedEvent7(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['signal.priced'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'signal.priced'
    entity_type: Annotated[
        Literal['signal'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'signal'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload23,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['signal']
var event_id : uuid.UUID
var event_type : Literal['signal.priced']
var model_config
var payload : Payload23

Inherited members

class WholesaleFeedEvent8 (**data: Any)
Expand source code
class WholesaleFeedEvent8(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['signal.removed'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'signal.removed'
    entity_type: Annotated[
        Literal['signal'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'signal'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload24,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['signal']
var event_id : uuid.UUID
var event_type : Literal['signal.removed']
var model_config
var payload : Payload24

Inherited members

class WholesaleFeedEvent9 (**data: Any)
Expand source code
class WholesaleFeedEvent9(AdCPBaseModel):
    event_id: Annotated[
        UUID,
        Field(
            description='Stable logical event identifier for this wholesale feed change. MUST equal the enclosing webhook notification_id. UUID v7 is RECOMMENDED so receivers can detect obvious out-of-order delivery; missed or distrusted pushes are repaired through list_products / get_signals.'
        ),
    ]
    event_type: Annotated[
        Literal['wholesale_feed.bulk_change'],
        Field(description='Discriminator. Determines the shape of `payload`.'),
    ] = 'wholesale_feed.bulk_change'
    entity_type: Annotated[
        Literal['feed'],
        Field(
            description="Entity class. 'product' for product.* events, 'signal' for signal.* events, 'feed' for wholesale_feed.bulk_change."
        ),
    ] = 'feed'
    entity_id: Annotated[
        str,
        Field(
            description='Entity identifier. For product.* events, the product_id. For signal.* events, the signal_agent_segment_id. For wholesale_feed.bulk_change, an agent-defined operation id.'
        ),
    ]
    created_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the agent emitted the event. Advisory — consumers MUST order by event_id (UUID v7), not by created_at, to avoid clock-skew artifacts.'
        ),
    ]
    payload: Annotated[
        Payload25,
        Field(
            description='Event-type-specific payload. Shape is determined by event_type per the oneOf below.'
        ),
    ]

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 created_at : pydantic.types.AwareDatetime
var entity_id : str
var entity_type : Literal['feed']
var event_id : uuid.UUID
var event_type : Literal['wholesale_feed.bulk_change']
var model_config
var payload : Payload25

Inherited members

class WholesaleFeedWebhook (**data: Any)
Expand source code
class WholesaleFeedWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Sender-generated key stable across retries of the same webhook fire. Receivers MUST dedupe by this key, scoped to the authenticated sender identity.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    notification_id: Annotated[
        UUID,
        Field(
            description='Stable identifier for this logical wholesale feed event. MUST equal event.event_id. Re-emissions of the same logical event reuse this value under a new idempotency_key.'
        ),
    ]
    notification_type: Annotated[
        NotificationType,
        Field(
            description='Wholesale feed notification type discriminator. MUST match event.event_type.'
        ),
    ]
    fired_at: Annotated[
        AwareDatetime,
        Field(
            description='ISO 8601 timestamp when the seller initiated this webhook fire. Distinct from event.created_at, which is when the seller observed or recorded the feed change.'
        ),
    ]
    subscriber_id: Annotated[
        str,
        Field(
            description='Identifies which notification_configs[] entry is receiving this fire. Echoed from the registered subscriber_id.',
            max_length=64,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,64}$',
        ),
    ]
    account_id: Annotated[
        str,
        Field(
            description='Seller account identifier for the account scope that registered this webhook through sync_accounts.accounts[].notification_configs[]. Required because wholesale feed webhooks are account-anchored notifications.'
        ),
    ]
    wholesale_feed_version: Annotated[
        str,
        Field(
            description='Opaque post-change version token for the affected wholesale feed. Store it only after applying the event. A stale mirror repairs with its last applied version; uncertain or bulk repair omits the conditional token.'
        ),
    ]
    product_payload_view: Annotated[
        ProductPayloadView | None,
        Field(
            description='Product representation selected by the receiving notification config. Present on product.* fires; canonical uses canonical_product/canonical_pricing_options and legacy uses product/pricing_options.'
        ),
    ] = None
    previous_wholesale_feed_version: Annotated[
        str | None,
        Field(
            description='Opaque version token for the affected wholesale feed before this change, when the seller can cheaply provide it. Receivers MAY use this to detect obvious gaps, but MUST NOT require it.'
        ),
    ] = None
    cache_scope: Annotated[
        CacheScope,
        Field(
            description='Cache layer affected by this change. MUST equal event.payload.applies_to.scope. Mirrors the cache_scope returned by list_products / get_signals for the affected wholesale feed.'
        ),
    ]
    event: Annotated[
        wholesale_feed_event.WholesaleFeedEvent,
        Field(
            description='The actual product, signal, or bulk-change event. Consumers MAY apply this payload to their local mirror. Before any binding action, or when ordering/gap checks fail, consumers MUST reconcile through list_products / get_signals.'
        ),
    ]
    ext: ext_1.ExtensionObject | 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 account_id : str
var cache_scope : CacheScope
var event : WholesaleFeedEvent1 | WholesaleFeedEvent2 | WholesaleFeedEvent3 | WholesaleFeedEvent4 | WholesaleFeedEvent5 | WholesaleFeedEvent6 | WholesaleFeedEvent7 | WholesaleFeedEvent8 | WholesaleFeedEvent9
var ext : ExtensionObject | None
var fired_at : pydantic.types.AwareDatetime
var idempotency_key : str
var model_config
var notification_id : uuid.UUID
var notification_type : NotificationType
var previous_wholesale_feed_version : str | None
var product_payload_view : ProductPayloadView | None
var subscriber_id : str
var wholesale_feed_version : str

Inherited members

class XEntityTypes (*args, **kwds)
Expand source code
class XEntityTypes(StrEnum):
    advertiser_brand = 'advertiser_brand'
    rights_holder_brand = 'rights_holder_brand'
    rights_grant = 'rights_grant'
    account = 'account'
    operator = 'operator'
    operator_unit = 'operator_unit'
    media_buy = 'media_buy'
    package = 'package'
    product = 'product'
    proposal = 'proposal'
    opportunity = 'opportunity'
    placement = 'placement'
    product_pricing_option = 'product_pricing_option'
    vendor_pricing_option = 'vendor_pricing_option'
    creative = 'creative'
    creative_revision = 'creative_revision'
    creative_representation = 'creative_representation'
    macro_declaration = 'macro_declaration'
    tracker_execution_selector = 'tracker_execution_selector'
    creative_locale_variant = 'creative_locale_variant'
    creative_format = 'creative_format'
    transformer = 'transformer'
    evaluator = 'evaluator'
    creative_evaluation = 'creative_evaluation'
    build_variant = 'build_variant'
    served_variant = 'served_variant'
    audience = 'audience'
    audience_evidence = 'audience_evidence'
    audience_evidence_snapshot = 'audience_evidence_snapshot'
    signal = 'signal'
    signal_activation_id = 'signal_activation_id'
    demographic_interval_id = 'demographic_interval_id'
    spot_airing = 'spot_airing'
    event_source = 'event_source'
    impairment = 'impairment'
    collection = 'collection'
    installment = 'installment'
    collection_list = 'collection_list'
    property_list = 'property_list'
    catalog = 'catalog'
    catalog_generation = 'catalog_generation'
    catalog_item = 'catalog_item'
    property = 'property'
    media_plan = 'media_plan'
    governance_plan = 'governance_plan'
    governance_registry_policy = 'governance_registry_policy'
    governance_policy_category = 'governance_policy_category'
    governance_policy_category_facet = 'governance_policy_category_facet'
    acceptance_policy_profile = 'acceptance_policy_profile'
    acceptance_policy_rule = 'acceptance_policy_rule'
    media_buy_change_term = 'media_buy_change_term'
    governance_inline_policy = 'governance_inline_policy'
    governance_check = 'governance_check'
    governance_delivery_statement = 'governance_delivery_statement'
    governance_delivery_observation = 'governance_delivery_observation'
    governance_outcome = 'governance_outcome'
    governance_adjustment = 'governance_adjustment'
    governance_adjustment_evidence = 'governance_adjustment_evidence'
    seller_adjustment = 'seller_adjustment'
    content_standards = 'content_standards'
    task = 'task'
    attestation_credential = 'attestation_credential'
    si_session = 'si_session'
    offering = 'offering'
    vendor_metric = 'vendor_metric'
    reporting_destination = 'reporting_destination'
    reporting_offering = 'reporting_offering'
    reporting_delivery_config = 'reporting_delivery_config'
    reporting_definition = 'reporting_definition'
    reporting_obligation = 'reporting_obligation'
    reporting_revision = 'reporting_revision'
    reporting_adjustment = 'reporting_adjustment'
    reporting_materialization = 'reporting_materialization'
    reporting_receipt = 'reporting_receipt'
    reporting_consumer_status = 'reporting_consumer_status'
    reporting_resource = 'reporting_resource'
    identity_relying_party = 'identity_relying_party'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var acceptance_policy_profile
var acceptance_policy_rule
var account
var advertiser_brand
var attestation_credential
var audience
var audience_evidence
var audience_evidence_snapshot
var build_variant
var catalog
var catalog_generation
var catalog_item
var collection
var collection_list
var content_standards
var creative
var creative_evaluation
var creative_format
var creative_locale_variant
var creative_representation
var creative_revision
var demographic_interval_id
var evaluator
var event_source
var governance_adjustment
var governance_adjustment_evidence
var governance_check
var governance_delivery_observation
var governance_delivery_statement
var governance_inline_policy
var governance_outcome
var governance_plan
var governance_policy_category
var governance_policy_category_facet
var governance_registry_policy
var identity_relying_party
var impairment
var installment
var macro_declaration
var media_buy
var media_buy_change_term
var media_plan
var offering
var operator
var operator_unit
var opportunity
var package
var placement
var product
var product_pricing_option
var property
var property_list
var proposal
var reporting_adjustment
var reporting_consumer_status
var reporting_definition
var reporting_delivery_config
var reporting_destination
var reporting_materialization
var reporting_obligation
var reporting_offering
var reporting_receipt
var reporting_resource
var reporting_revision
var rights_grant
var rights_holder_brand
var seller_adjustment
var served_variant
var si_session
var signal
var signal_activation_id
var spot_airing
var task
var tracker_execution_selector
var transformer
var vendor_metric
var vendor_pricing_option