Module adcp.types.seller

AdCP seller types — curated partial surface.

Sell-side (SSP / publisher) surface — products / offerings, properties and property lists, content standards, governance, catalog sync, account financials.

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

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

from adcp.types.seller import Product

Classes

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 AuthorizedAgents (**data: Any)
Expand source code
class AuthorizedAgents1(AuthorizedAgentBaseFields):
    model_config = ConfigDict(
        extra='allow',
    )
    authorization_type: Annotated[
        Literal['property_ids'],
        Field(description='Discriminator indicating authorization by specific property IDs'),
    ] = 'property_ids'
    property_ids: Annotated[
        list[property_id.PropertyId],
        Field(
            description='Property IDs this agent is authorized for. Resolved against the top-level properties array in this file',
            min_length=1,
        ),
    ]
    collections: Annotated[
        list[collection_selector.CollectionSelector] | None,
        Field(
            description="Optional collection constraints. When present, authorization only applies to inventory associated with these collections. A selector without collection_ids grants for all collections declared in that selector's publisher_domain adagents.json (the bulk-grant form for owner-sold carriage).",
            min_length=1,
        ),
    ] = None
    placement_ids: Annotated[
        list[str] | None,
        Field(
            description='Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.',
            min_length=1,
        ),
    ] = None
    placement_tags: Annotated[
        list[str] | None,
        Field(
            description='Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.',
            min_length=1,
        ),
    ] = None
    delegation_type: Annotated[
        DelegationType | None,
        Field(
            description="Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint."
        ),
    ] = None
    exclusive: Annotated[
        StrictBool | None,
        Field(
            description="Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory."
        ),
    ] = None
    countries: Annotated[
        list[Country] | None,
        Field(
            description='Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.',
            min_length=1,
        ),
    ] = None
    effective_from: Annotated[
        AwareDatetime | None,
        Field(description='Optional start time for this authorization window.'),
    ] = None
    effective_until: Annotated[
        AwareDatetime | None, Field(description='Optional end time for this authorization 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

Subclasses

Class variables

var authorization_type : Literal['property_ids']
var collections : list[CollectionSelector] | None
var countries : list[Country] | None
var delegation_type : DelegationType | None
var effective_from : pydantic.types.AwareDatetime | None
var effective_until : pydantic.types.AwareDatetime | None
var exclusive : bool | None
var model_config
var placement_ids : list[str] | None
var placement_tags : list[str] | None
var property_ids : list[PropertyId]

Inherited members

class Catalog (**data: Any)
Expand source code
class Catalog(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_id: Annotated[
        str | None,
        Field(
            description="Buyer's identifier for this catalog. Required when syncing via sync_catalogs. When used in creatives, references a previously synced catalog on the account."
        ),
    ] = None
    name: Annotated[
        str | None,
        Field(
            description="Human-readable name for this catalog (e.g., 'Summer Products 2025', 'Amsterdam Store Locations')."
        ),
    ] = None
    type: Annotated[
        catalog_type.CatalogType,
        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."
        ),
    ]
    url: Annotated[
        AnyUrl | None,
        Field(
            description="URL to an external catalog feed. The platform fetches and resolves items from this URL. For offering-type catalogs, the feed contains an array of Offering objects. For other types, the feed format is determined by feed_format. When omitted with type 'product', the platform uses its synced copy of the brand's product catalog."
        ),
    ] = None
    feed_format: Annotated[
        feed_format_1.FeedFormat | None,
        Field(
            description='Format of the external feed at url. Required when url points to a non-AdCP feed (e.g., Google Merchant Center XML, Meta Product Catalog). Omit for offering-type catalogs where the feed is native AdCP JSON.'
        ),
    ] = None
    update_frequency: Annotated[
        update_frequency_1.UpdateFrequency | None,
        Field(
            description='How often the platform should re-fetch the feed from url. Only applicable when url is provided. Platforms may use this as a hint for polling schedules.'
        ),
    ] = None
    items: Annotated[
        list[dict[str, Any]] | None,
        Field(
            description="Inline catalog data. The item schema depends on the catalog type: Offering objects for 'offering', StoreItem for 'store', HotelItem for 'hotel', FlightItem for 'flight', JobItem for 'job', VehicleItem for 'vehicle', RealEstateItem for 'real_estate', EducationItem for 'education', DestinationItem for 'destination', AppItem for 'app', or freeform objects for 'product', 'inventory', and 'promotion'. Mutually exclusive with url — provide one or the other, not both. Implementations should validate items against the type-specific schema.",
            min_length=1,
        ),
    ] = 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')."
        ),
    ] = None
    conversion_events: Annotated[
        list[event_type.EventType] | None,
        Field(
            description="Event types that represent conversions for items in this catalog. Declares what events the platform should attribute to catalog items — e.g., a job catalog converts via submit_application, a product catalog via purchase. The event's content_ids field carries the item IDs that connect back to catalog items. Use content_id_type to declare what identifier type content_ids values represent.",
            min_length=1,
        ),
    ] = None
    content_id_type: Annotated[
        content_id_type_1.ContentIdType | None,
        Field(
            description="Identifier type that the event's content_ids field should be matched against for items in this catalog. For example, 'gtin' means content_ids values are Global Trade Item Numbers, 'sku' means retailer SKUs. Omit when using a custom identifier scheme not listed in the enum."
        ),
    ] = None
    feed_field_mappings: Annotated[
        list[catalog_field_mapping.CatalogFieldMapping] | None,
        Field(
            description='Declarative normalization rules for external feeds. Maps non-standard feed field names, date formats, price encodings, and image URLs to the AdCP catalog item schema. Applied during sync_catalogs ingestion. Supports field renames, named transforms (date, divide, boolean, split), static literal injection, and assignment of image URLs to typed asset pools.',
            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 catalog_id : str | None
var category : str | None
var content_id_type : ContentIdType | None
var conversion_events : list[EventType] | None
var feed_field_mappings : list[CatalogFieldMapping] | None
var feed_format : FeedFormat | None
var gtins : list[Gtin] | None
var ids : list[str] | None
var items : list[dict[str, typing.Any]] | None
var model_config
var name : str | None
var query : str | None
var tags : list[str] | None
var type : CatalogType
var update_frequency : UpdateFrequency | None
var url : pydantic.networks.AnyUrl | None
class SyncCatalogResult (**data: Any)
Expand source code
class Catalog(AdcpVersionEnvelope):
    model_config = ConfigDict(extra='allow')
    catalog_id: str
    catalog_generation: Annotated[str, StringConstraints(min_length=1, max_length=255)] | None = None
    action: catalog_action_1.CatalogAction
    platform_id: str | None = None
    item_count: Annotated[int, Field(ge=0)] | None = None
    items_approved: Annotated[int, Field(ge=0)] | None = None
    items_pending: Annotated[int, Field(ge=0)] | None = None
    items_rejected: Annotated[int, Field(ge=0)] | None = None
    item_issues: list[ItemIssue] | None = None
    last_synced_at: AwareDatetime | None = None
    next_fetch_at: AwareDatetime | None = None
    changes: list[str] | None = None
    errors: list[error_1.Error] | None = None
    warnings: 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 action : CatalogAction
var catalog_generation : str | None
var catalog_id : str
var changes : list[str] | None
var errors : list[Error] | None
var item_count : int | None
var item_issues : list[ItemIssue] | None
var items_approved : int | None
var items_pending : int | None
var items_rejected : int | None
var last_synced_at : pydantic.types.AwareDatetime | None
var model_config
var next_fetch_at : pydantic.types.AwareDatetime | None
var platform_id : str | None
var warnings : list[str] | 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 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 CheckGovernanceRequest (**data: Any)
Expand source code
class CheckGovernanceRequest(AdcpRequest, CheckGovernanceRequest3):
    'Universal governance check for campaign actions. The governance agent infers the check type from the fields present: tool+payload = intent check (proposed, orchestrator-side); planned_delivery or delivery_metrics with governance_context = execution or lifecycle check (committed, service-side). Proposal acceptance supplies the immutable proposal separately so governance can inspect its typed commercial terms while payload remains the exact downstream arguments. MediaBuy controls use buyer-proposed and seller-computed positive-delta ceilings. The first check is addressed by plan_id. Subsequent service-side checks use the opaque governance_context as the authoritative plan binding.'

Universal governance check for campaign actions. The governance agent infers the check type from the fields present: tool+payload = intent check (proposed, orchestrator-side); planned_delivery or delivery_metrics with governance_context = execution or lifecycle check (committed, service-side). Proposal acceptance supplies the immutable proposal separately so governance can inspect its typed commercial terms while payload remains the exact downstream arguments. MediaBuy controls use buyer-proposed and seller-computed positive-delta ceilings. The first check is addressed by plan_id. Subsequent service-side checks use the opaque governance_context as the authoritative plan binding.

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

Raises [ValidationError][pydantic_core.ValidationError] if the input data 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 CheckGovernanceResponse (**data: Any)
Expand source code
class CheckGovernanceResponse(AdcpResponse, AdcpVersionEnvelope):
    @model_validator(mode='before')
    @classmethod
    def _status_to_verdict(cls, data: Any) -> Any:
        if isinstance(data, dict) and 'verdict' not in data and 'status' in data:
            data = dict(data)
            data['verdict'] = data['status']
        return data

    model_config = ConfigDict(
        extra='allow',
    )
    check_id: Annotated[
        str,
        Field(
            description='Unique identifier for this governance check record. Use in report_plan_outcome to link outcomes to the check that authorized them.'
        ),
    ]
    verdict: Annotated[
        governance_decision.GovernanceDecision,
        Field(
            description='Governance verdict: approved | denied | conditions. Renamed from `status` in 3.1 to free the top-level `status` key for the envelope task-status (TaskStatus) under MCP flat-on-the-wire serialization. The enum values are unchanged; only the property name moved.'
        ),
    ]
    check_type: Annotated[
        CheckType | None,
        Field(
            description='Check shape that produced the verdict. Required for the cross-role governance_enforcement contract. Its presence selects the modern verdict-specific response rules; its absence selects the deprecated legacy 3.x compatibility shape. Intent checks may return conditions; execution checks are binary approved or denied.'
        ),
    ] = None
    plan_id: Annotated[
        str | None,
        Field(
            description='Plan identifier echoed on an initial plan-addressed check. Optional on continuation checks addressed by governance_context; services do not need this value and MUST treat the token binding as authoritative.'
        ),
    ] = None
    explanation: Annotated[
        str, Field(description='Human-readable explanation of the governance decision.')
    ]
    findings: Annotated[
        list[Finding] | None,
        Field(
            description="Specific issues found during the governance check. Present when verdict is 'denied' or 'conditions'. MAY also be present on 'approved' for informational findings (e.g., budget approaching limit)."
        ),
    ] = None
    conditions: Annotated[
        list[Condition] | None,
        Field(
            description="Intent-phase counterproposal. Present only when verdict is 'conditions'. It does not authorize execution and MUST NOT be returned for execution or lifecycle checks. Each field path is rooted at the complete check_governance request arguments, so both payload.* and proposed_commitment.* can be addressed. After applying conditions, the caller MUST re-call check_governance with the adjusted parameters and receive approved before proceeding."
        ),
    ] = None
    consultation_context: Annotated[
        str | None,
        Field(
            description='Opaque negotiation handle present only with modern conditions responses. It carries no authorization and MUST NOT be sent to a downstream service. The governance agent MUST bind it server-side to the authenticated principal, caller, plan, tool, purchase type, and target audience, and reject a re-check if any binding changes. The buyer returns it only on the adjusted intent re-check.',
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]+$',
        ),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None,
        Field(
            description="When this approval expires. In the cross-role shape, present only when verdict is 'approved'. Deprecated legacy conditions responses may also carry it for 3.x compatibility. The caller must act before this time or re-call check_governance. A lapsed approval is no approval."
        ),
    ] = None
    next_check: Annotated[
        AwareDatetime | None,
        Field(
            description='When the seller should next call check_governance with delivery metrics. Present when the governance agent expects ongoing delivery reporting.'
        ),
    ] = None
    delivery_statement: Annotated[
        DeliveryStatement | None,
        Field(
            description='Canonical seller-attributed delivery statement retained by governance. Present on delivery execution checks. The buyer binds any later observation to this exact statement through report_plan_outcome.'
        ),
    ] = None
    categories_evaluated: Annotated[
        list[str] | None,
        Field(
            description="Governance categories evaluated during this check. Each value is an **agent-internal** label (e.g., `budget_authority`, `regulatory_compliance`, or any internal-reviewer key the agent's policy model defines) — not a protocol-level enum. Since one governance agent per account composes all specialist review behind its single endpoint, `categories_evaluated` is how that internal decomposition surfaces to auditors. Consumers MUST treat values as opaque labels for display and audit, not as a machine-level contract."
        ),
    ] = None
    policies_evaluated: Annotated[
        list[str] | None,
        Field(
            description="Policy IDs evaluated during this check. Includes registry policy IDs (resolved via the policy registry) and any inline `policy_id`s declared in the plan's `custom_policies`."
        ),
    ] = None
    mode: Annotated[
        governance_mode.GovernanceMode | None,
        Field(
            description='Governance enforcement mode active when this check was evaluated. Allows counterparties, regulators, and auditors to distinguish whether a finding blocked execution (enforce) or was logged silently (audit).'
        ),
    ] = None
    runtime_attestation_evaluations: Annotated[
        list[RuntimeAttestationEvaluation] | None,
        Field(
            description="Evaluator-of-record results for request runtime_attestations[], in the same order and with exactly one result per presentation. Each result is the shared AttestationEvaluation and MUST bind to this response's check_id through action_binding.action_type = https://adcontextprotocol.org/actions/governance-check and action_binding.action_id = check_id. The signed governance_context MUST bind the same reference_digest/outcome pairs; large evidence stays in the audit log rather than the token.",
            max_length=10,
            min_length=1,
        ),
    ] = None
    runtime_attestation_binding_digest: Annotated[
        str | None,
        Field(
            description='SHA-256 of RFC 8785 JCS({ evaluations: runtime_attestation_evaluations, findings: attestation_bound_findings }), where attestation_bound_findings is the response findings[] subset carrying attestation_reference_digest, preserved in response order. Required whenever runtime_attestation_evaluations is present. The governance_context JWS carries this exact value as runtime_attestation_binding_digest; get_plan_audit_logs retains ordered {reference, evaluation} pairs so auditors can first recompute every reference_digest and then prove which evaluations and findings the signed decision relied on.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    governance_context: Annotated[
        str | None,
        Field(
            description='Opaque authorization context for this governed action. Present only when verdict is approved; denied and conditions responses MUST NOT carry it. The buyer attaches it to the protocol envelope when sending the governed request. The service persists and forwards it on subsequent execution and lifecycle checks without requiring plan_id.\n\nGovernance agents MUST emit a compact JWS per the AdCP JWS profile. Verifiers validate the standard authorization claims but MUST NOT interpret embedded governance state for business logic. The issuing governance agent uses the token to recover its internal plan and decision state.',
            max_length=4096,
            min_length=1,
            pattern='^[\\x20-\\x7E]+$',
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

Ancestors

Class variables

var categories_evaluated : list[str] | None
var check_id : str
var check_type : CheckType | None
var conditions : list[Condition] | None
var consultation_context : str | None
var context : ContextObject | None
var delivery_statement : DeliveryStatement | None
var expires_at : pydantic.types.AwareDatetime | None
var explanation : str
var ext : ExtensionObject | None
var findings : list[Finding] | None
var governance_context : str | None
var mode : GovernanceMode | None
var model_config
var next_check : pydantic.types.AwareDatetime | None
var plan_id : str | None
var policies_evaluated : list[str] | None
var runtime_attestation_binding_digest : str | None
var runtime_attestation_evaluations : list[RuntimeAttestationEvaluation] | None
var verdict : GovernanceDecision

Inherited members

class ContentStandards (**data: Any)
Expand source code
class ContentStandards(AdCPBaseModel):
    standards_id: Annotated[
        str, Field(description='Unique identifier for this standards configuration')
    ]
    name: Annotated[
        str | None, Field(description='Human-readable name for this standards configuration')
    ] = None
    countries_all: Annotated[
        list[str] | None,
        Field(
            description='ISO 3166-1 alpha-2 country codes. Standards apply in ALL listed countries (AND logic).',
            min_length=1,
        ),
    ] = None
    channels_any: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description='Advertising channels. Standards apply to ANY of the listed channels (OR logic).',
            min_length=1,
        ),
    ] = None
    languages_any: Annotated[
        list[str] | None,
        Field(
            description="BCP 47 language tags (e.g., 'en', 'de', 'fr'). Standards apply to content in ANY of these languages (OR logic). Content in unlisted languages is not covered by these standards.",
            min_length=1,
        ),
    ] = None
    policies: Annotated[
        list[policy_entry.PolicyEntry] | None,
        Field(
            description='Bespoke policies for this content-standards configuration, using the same shape as registry entries. Each policy is addressable by policy_id; governance findings reference the policy_id that triggered them.',
            min_length=1,
        ),
    ] = None
    calibration_exemplars: Annotated[
        CalibrationExemplars | None,
        Field(
            description='Training/test set to calibrate policy interpretation. Provides concrete examples of pass/fail decisions.'
        ),
    ] = None
    pricing_options: Annotated[
        list[vendor_pricing_option.VendorPricingOption] | None,
        Field(
            description='Pricing options for this content standards service. The buyer passes the selected pricing_option_id in report_usage for billing verification.',
            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 calibration_exemplars : CalibrationExemplars | None
var channels_any : list[MediaChannel] | None
var countries_all : list[str] | None
var ext : ExtensionObject | None
var languages_any : list[str] | None
var model_config
var name : str | None
var policies : list[PolicyEntry] | None
var pricing_options : list[VendorPricingOption7 | VendorPricingOption8 | VendorPricingOption9 | VendorPricingOption10 | VendorPricingOption11] | None
var standards_id : str

Inherited members

class CreateContentStandardsRequest (**data: Any)
Expand source code
class CreateContentStandardsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    scope: Annotated[Scope, Field(description='Where this standards configuration applies')]
    registry_policy_ids: Annotated[
        list[str] | None,
        Field(
            description="Registry policy IDs to use as the evaluation basis for this content standard. When provided, the agent resolves policies from the registry and uses their policy text and exemplars as the evaluation criteria. The 'policy' field becomes optional when registry_policy_ids is provided."
        ),
    ] = None
    policies: Annotated[
        list[policy_entry.PolicyEntry] | None,
        Field(
            description='Bespoke policies for this content-standards configuration, using the same shape as registry entries. Each policy is addressable by policy_id and carries its own enforcement (must|should); governance findings reference the policy_id that triggered them. Inline bespoke policies can omit version/name/category (defaulted by the server). Combines with registry_policy_ids — registry policies and bespoke policies are both evaluated. Bespoke policy_ids MUST be flat (no colons/slashes) to avoid collision with namespaced registry ids.',
            min_length=1,
        ),
    ] = None
    calibration_exemplars: Annotated[
        CalibrationExemplars | None,
        Field(
            description='Training/test set to calibrate policy interpretation. Use URL references for pages to be fetched and analyzed, or full artifacts for pre-extracted content.'
        ),
    ] = None
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for this request. Prevents duplicate content standards creation on retries. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> CreateContentStandardsRequest:
        # ``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 (('policies',), ('registry_policy_ids',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'CreateContentStandardsRequest requires at least one of these field groups: policies | registry_policy_ids'
        )

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

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

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

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

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

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

Ancestors

Class variables

var calibration_exemplars : CalibrationExemplars | None
var context : ContextObject | None
var ext : ExtensionObject | None
var idempotency_key : str
var model_config
var policies : list[PolicyEntry] | None
var registry_policy_ids : list[str] | None
var scope : Scope

Inherited members

class CreatePropertyListRequest (**data: Any)
Expand source code
class CreatePropertyListRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account that will own the list. Pass a natural key (brand, operator, optional sandbox) or a seller-assigned account_id from list_accounts. When omitted, this task applies its task-local single-account shortcut: if exactly one account is accessible to the authenticated caller, the seller may assign the list to that account; otherwise it MUST return an account-required or ambiguous-account error. Omission MUST NOT mean an undocumented credential-local default account.'
        ),
    ] = None
    name: Annotated[str, Field(description='Human-readable name for the list')]
    description: Annotated[str | None, Field(description="Description of the list's purpose")] = (
        None
    )
    base_properties: Annotated[
        list[base_property_source.BasePropertySource] | None,
        Field(
            description="Array of property sources to evaluate. Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers). If omitted, queries the agent's entire property database.",
            min_length=1,
        ),
    ] = None
    filters: Annotated[
        property_list_filters.PropertyListFilters | None,
        Field(description='Dynamic filters to apply when resolving the list'),
    ] = None
    brand: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description='Brand reference. When provided, the agent automatically applies appropriate rules based on brand characteristics (industry, target_audience, etc.). Resolved at execution time.'
        ),
    ] = None
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for this request. Prevents duplicate property list creation on retries. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var base_properties : list[BasePropertySource1 | BasePropertySource2 | BasePropertySource3] | None
var brand : BrandReference | None
var context : ContextObject | None
var description : str | None
var ext : ExtensionObject | None
var filters : PropertyListFilters | None
var idempotency_key : str
var model_config
var name : str

Inherited members

class CreatePropertyListResponse (**data: Any)
Expand source code
class CreatePropertyListResponse(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    list: Annotated[property_list.PropertyList, Field(description='The created property list')]
    auth_token: Annotated[
        str,
        Field(
            description='Token that can be shared with sellers to authorize fetching this list. Store this - it is only returned at creation time.'
        ),
    ]
    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
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

Ancestors

Class variables

var auth_token : str
var context : ContextObject | None
var ext : ExtensionObject | None
var list : PropertyList
var model_config
var replayed : bool | None

Inherited members

class CreditLimit (**data: Any)
Expand source code
class CreditLimit(AdcpVersionEnvelope):
    model_config = ConfigDict(extra='allow')
    amount: Annotated[float, Field(ge=0)]
    currency: Annotated[str, StringConstraints(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 DeletePropertyListRequest (**data: Any)
Expand source code
class DeletePropertyListRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    list_id: Annotated[str, Field(description='ID of the property list to delete')]
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account that owns the list. Required when the authenticated agent has access to multiple accounts; optional otherwise.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for at-most-once execution. If a request with the same key has already been processed, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var context : ContextObject | None
var ext : ExtensionObject | None
var idempotency_key : str
var list_id : str
var model_config

Inherited members

class GetAccountFinancialsRequest (**data: Any)
Expand source code
class GetAccountFinancialsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    account: Annotated[
        account_ref.AccountReference,
        Field(description='Account to query financials for. Must be an operator-billed account.'),
    ]
    period: Annotated[
        date_range.DateRange | None,
        Field(
            description='Date range for the spend summary. Defaults to the current billing cycle if omitted.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2
var context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var period : DateRange | None

Inherited members

class GetContentStandardsRequest (**data: Any)
Expand source code
class GetContentStandardsRequest(AdcpRequest, AdcpVersionEnvelope):
    standards_id: Annotated[
        str, Field(description='Identifier for the standards configuration to retrieve')
    ]
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var standards_id : str

Inherited members

class GetPlanAuditLogsRequest (**data: Any)
Expand source code
class GetPlanAuditLogsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    plan_ids: Annotated[
        list[str] | None,
        Field(
            description='Plan IDs to retrieve. For a single plan, pass a one-element array. Plans uniquely scope account and operator; do not include a separate `account` field — the governance agent resolves account from each plan. Including `account` is rejected by `additionalProperties: false`.',
            min_length=1,
        ),
    ] = None
    portfolio_plan_ids: Annotated[
        list[str] | None,
        Field(
            description='Portfolio plan IDs. The governance agent expands each to its member_plan_ids and returns combined audit data.',
            min_length=1,
        ),
    ] = None
    governance_contexts: Annotated[
        list[str] | None,
        Field(
            description='Filter audit entries by governance context. Returns only checks and outcomes that share these governance contexts, enabling lifecycle tracing across purchase types.',
            min_length=1,
        ),
    ] = None
    purchase_types: Annotated[
        list[purchase_type.PurchaseType] | None,
        Field(
            description="Filter audit entries by purchase type. Returns only checks and outcomes matching these purchase types (e.g., ['rights_license'] to see all rights activity).",
            min_length=1,
        ),
    ] = None
    include_entries: Annotated[
        StrictBool | None, Field(description='Include the full audit trail. Default: false.')
    ] = False
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> GetPlanAuditLogsRequest:
        # ``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 (('plan_ids',), ('portfolio_plan_ids',), ('governance_contexts',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'GetPlanAuditLogsRequest requires at least one of these field groups: plan_ids | portfolio_plan_ids | governance_contexts'
        )

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

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

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

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

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

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

Ancestors

Class variables

var context : ContextObject | None
var ext : ExtensionObject | None
var governance_contexts : list[str] | None
var include_entries : bool | None
var model_config
var plan_ids : list[str] | None
var portfolio_plan_ids : list[str] | None
var purchase_types : list[PurchaseType] | None

Inherited members

class GetPropertyListRequest (**data: Any)
Expand source code
class GetPropertyListRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    list_id: Annotated[str, Field(description='ID of the property list to retrieve')]
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account that owns the list. Required when the authenticated agent has access to multiple accounts and the list_id is not globally unique within that scope; optional otherwise.'
        ),
    ] = None
    resolve: Annotated[
        StrictBool | None,
        Field(
            description='Whether to apply filters and return resolved identifiers (default: true)'
        ),
    ] = True
    pagination: Annotated[
        Pagination | None,
        Field(
            description='Pagination parameters. Uses higher limits than standard pagination because property lists can contain tens of thousands of identifiers.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var context : ContextObject | None
var ext : ExtensionObject | None
var list_id : str
var model_config
var pagination : Pagination | None
var resolve : bool | None

Inherited members

class GetPropertyListResponse (**data: Any)
Expand source code
class GetPropertyListResponse(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    list: Annotated[
        property_list.PropertyList,
        Field(description='The property list metadata (always returned)'),
    ]
    identifiers: Annotated[
        _list[identifier.Identifier] | None,
        Field(
            description='Resolved identifiers that passed filters (if resolve=true). Cache these locally for real-time use.'
        ),
    ] = None
    pagination: pagination_response.PaginationResponse | None = None
    resolved_at: Annotated[
        AwareDatetime | None, Field(description='When the list was resolved')
    ] = None
    cache_valid_until: Annotated[
        AwareDatetime | None,
        Field(
            description='Cache expiration timestamp. Re-fetch the list after this time to get updated identifiers.'
        ),
    ] = None
    coverage_gaps: Annotated[
        dict[str, _list[identifier.Identifier]] | None,
        Field(
            description="Properties included in the list despite missing feature data. Only present when a feature_requirement has if_not_covered='include'. Maps feature_id to list of identifiers not covered for that feature."
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

Ancestors

Class variables

var cache_valid_until : pydantic.types.AwareDatetime | None
var context : ContextObject | None
var coverage_gaps : dict[str, list[Identifier]] | None
var ext : ExtensionObject | None
var identifiers : list[Identifier] | None
var list : PropertyList
var model_config
var pagination : PaginationResponse | None
var resolved_at : pydantic.types.AwareDatetime | None

Inherited members

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.')]
    authentication: Annotated[
        Authentication,
        Field(description='Authentication the seller presents when calling this governance 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 authentication : Authentication
var model_config
var url : pydantic.networks.AnyUrl

Inherited members

class ListAccountsRequest (**data: Any)
Expand source code
class ListAccountsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Optional exact account filter. Use `account_id` to retrieve one known seller/storefront account, or the complete natural key (`brand` + `operator` + optional `operator_unit`, fixed `currency`, buyer-selected account `timezone`, and `sandbox`) for buyer-declared accounts. When present, the seller returns only matching accounts visible to the authenticated caller.'
        ),
    ] = None
    status: Annotated[
        Status | None,
        Field(description='Filter accounts by status. Omit to return accounts in all statuses.'),
    ] = None
    pagination: pagination_request.PaginationRequest | None = None
    sandbox: Annotated[
        StrictBool | None,
        Field(
            description='Filter by sandbox status. true returns only sandbox accounts, false returns only production accounts. Omit to return all accounts. Primarily used with account-id namespaces where sandbox accounts are pre-existing test accounts on the platform.'
        ),
    ] = None
    include_webhook_activity: Annotated[
        StrictBool | None,
        Field(
            description='When true, request recent webhook delivery attempts for each returned account in account.webhook_activity[]. Sellers MAY omit webhook_activity if they do not expose this debug log; when present, three-state semantics match the shared webhook_activity[] contract.'
        ),
    ] = False
    webhook_activity_limit: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of webhook_activity[] records to return per account when include_webhook_activity is true.',
            ge=1,
            le=200,
        ),
    ] = 50
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var context : ContextObject | None
var ext : ExtensionObject | None
var include_webhook_activity : bool | None
var model_config
var pagination : PaginationRequest | None
var sandbox : bool | None
var status : Status | None
var webhook_activity_limit : int | None

Inherited members

class ListContentStandardsRequest (**data: Any)
Expand source code
class ListContentStandardsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    channels: Annotated[
        list[channels_1.MediaChannel] | None, Field(description='Filter by channel', min_length=1)
    ] = None
    languages: Annotated[
        list[str] | None, Field(description='Filter by BCP 47 language tags', min_length=1)
    ] = None
    countries: Annotated[
        list[str] | None,
        Field(description='Filter by ISO 3166-1 alpha-2 country codes', min_length=1),
    ] = None
    pagination: pagination_request.PaginationRequest | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var channels : list[MediaChannel] | None
var context : ContextObject | None
var countries : list[str] | None
var ext : ExtensionObject | None
var languages : list[str] | None
var model_config
var pagination : PaginationRequest | None

Inherited members

class ListPropertyListsRequest (**data: Any)
Expand source code
class ListPropertyListsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Filter to lists owned by this account. When omitted, returns lists across all accounts accessible to the authenticated agent.'
        ),
    ] = None
    name_contains: Annotated[
        str | None, Field(description='Filter to lists whose name contains this string')
    ] = None
    pagination: pagination_request.PaginationRequest | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var name_contains : str | None
var pagination : PaginationRequest | None

Inherited members

class ListPropertyListsResponse (**data: Any)
Expand source code
class ListPropertyListsResponse(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    lists: Annotated[
        list[property_list.PropertyList],
        Field(description='Array of property lists (metadata only, not resolved properties)'),
    ]
    pagination: pagination_response.PaginationResponse | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

Ancestors

Class variables

var context : ContextObject | None
var ext : ExtensionObject | None
var lists : list[PropertyList]
var model_config
var pagination : PaginationResponse | None

Inherited members

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 PaymentTerms (*args, **kwds)
Expand source code
class PaymentTerms(StrEnum):
    net_15 = 'net_15'
    net_30 = 'net_30'
    net_45 = 'net_45'
    net_60 = 'net_60'
    net_90 = 'net_90'
    prepay = 'prepay'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var net_15
var net_30
var net_45
var net_60
var net_90
var prepay
class Product (**data: Any)
Expand source code
class Product(_LegacyProduct, CanonicalBoundaryModel):
    """Canonical product; formats, placements and pricing are canonical."""

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

    format_options: list[Format] = Field(  # type: ignore[assignment]
        min_length=1, description="Canonical creative formats accepted by this product."
    )
    placements: list[Placement] | None = Field(default=None, min_length=1)  # type: ignore[assignment]
    pricing_options: list[CanonicalPricingOption] = Field(min_length=1)

Canonical product; formats, placements and pricing are canonical.

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

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

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

Ancestors

Class variables

var format_ids : list[FormatReferenceStructuredObject] | None
var format_options : list[Format]
var model_config
var placements : list[Placement] | None
var pricing_options : list[CpmPricingOption | VcpmPricingOption | CpcPricingOption | CpcvPricingOption | CpvPricingOption | CppPricingOption | CpaPricingOption | RevenueSharePricingOption | FlatRatePricingOption | TimeBasedPricingOption]

Instance variables

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

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

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

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

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.
var outcome_measurement : OutcomeMeasurement | 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 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 PropertyList (**data: Any)
Expand source code
class PropertyList(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    list_id: Annotated[str, Field(description='Unique identifier for this property list')]
    name: Annotated[str, Field(description='Human-readable name for the list')]
    description: Annotated[str | None, Field(description="Description of the list's purpose")] = (
        None
    )
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account that owns this list. Returned as account_id form (seller-assigned identifier).'
        ),
    ] = None
    base_properties: Annotated[
        list[base_property_source.BasePropertySource] | None,
        Field(
            description="Array of property sources to evaluate. Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers). If omitted, queries the agent's entire property database."
        ),
    ] = None
    filters: Annotated[
        property_list_filters.PropertyListFilters | None,
        Field(description='Dynamic filters applied when resolving the list'),
    ] = None
    brand: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description='Brand reference used to automatically apply appropriate rules. Resolved to full brand identity at execution time.'
        ),
    ] = None
    webhook_url: Annotated[
        AnyUrl | None,
        Field(description='URL to receive notifications when the resolved list changes'),
    ] = None
    cache_duration_hours: Annotated[
        SchemaInt | None,
        Field(
            description='Recommended cache duration for resolved list. Consumers should re-fetch after this period.',
            ge=1,
        ),
    ] = 24
    created_at: Annotated[AwareDatetime | None, Field(description='When the list was created')] = (
        None
    )
    updated_at: Annotated[
        AwareDatetime | None, Field(description='When the list was last modified')
    ] = None
    property_count: Annotated[
        SchemaInt | None,
        Field(description='Number of properties in the resolved list (at time of last resolution)'),
    ] = None
    pricing_options: Annotated[
        list[vendor_pricing_option.VendorPricingOption] | None,
        Field(
            description='Pricing options for this property list. Present when the requesting account has a billing relationship with the list provider. The buyer passes the selected pricing_option_id in report_usage.',
            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 : AccountReference1 | AccountReference2 | None
var base_properties : list[BasePropertySource1 | BasePropertySource2 | BasePropertySource3] | None
var brand : BrandReference | None
var cache_duration_hours : int | None
var created_at : pydantic.types.AwareDatetime | None
var description : str | None
var filters : PropertyListFilters | None
var list_id : str
var model_config
var name : str
var pricing_options : list[VendorPricingOption7 | VendorPricingOption8 | VendorPricingOption9 | VendorPricingOption10 | VendorPricingOption11] | None
var property_count : int | None
var updated_at : pydantic.types.AwareDatetime | None
var webhook_url : pydantic.networks.AnyUrl | None

Inherited members

class PropertyListFilters (**data: Any)
Expand source code
class PropertyListFilters(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    countries_all: Annotated[
        list[CountriesAllItem] | None,
        Field(
            description='Property must have feature data for ALL listed countries (ISO codes). When omitted, no country restriction is applied.',
            min_length=1,
        ),
    ] = None
    channels_any: Annotated[
        list[channels.MediaChannel] | None,
        Field(
            description='Property must support ANY of the listed channels. When omitted, no channel restriction is applied.',
            min_length=1,
        ),
    ] = None
    property_types: Annotated[
        list[property_type.PropertyType] | None,
        Field(description='Filter to these property types', min_length=1),
    ] = None
    feature_requirements: Annotated[
        list[feature_requirement.FeatureRequirement] | None,
        Field(
            description='Feature-based requirements. Property must pass ALL requirements (AND logic).',
            min_length=1,
        ),
    ] = None
    exclude_identifiers: Annotated[
        list[identifier.Identifier] | None,
        Field(description='Identifiers to always exclude from results', 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 channels_any : list[MediaChannel] | None
var countries_all : list[CountriesAllItem] | None
var exclude_identifiers : list[Identifier] | None
var feature_requirements : list[FeatureRequirement] | None
var model_config
var property_types : list[PropertyType] | None

Inherited members

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 PropertyType (*args, **kwds)
Expand source code
class PropertyType(StrEnum):
    website = 'website'
    mobile_app = 'mobile_app'
    ctv_app = 'ctv_app'
    desktop_app = 'desktop_app'
    dooh = 'dooh'
    podcast = 'podcast'
    radio = 'radio'
    linear_tv = 'linear_tv'
    streaming_audio = 'streaming_audio'
    ai_assistant = 'ai_assistant'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var ai_assistant
var ctv_app
var desktop_app
var dooh
var linear_tv
var mobile_app
var podcast
var radio
var streaming_audio
var website
class ReportPlanOutcomeRequest (**data: Any)
Expand source code
class ReportPlanOutcomeRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    plan_id: Annotated[
        str,
        Field(
            description='The plan this outcome is for. The plan is owned by the authenticated buyer that synchronized it; plan_id is an identifier, not an account credential. Completed and failed settlements inherit their commercial binding from the exact approved check tuple.'
        ),
    ]
    check_id: Annotated[
        str | None,
        Field(
            description='The check_id from check_governance. Required for completed and failed outcomes and for buyer delivery observations. A delivery observation names the exact seller delivery check whose canonical statement is being compared.'
        ),
    ] = None
    idempotency_key: Annotated[
        str,
        Field(
            description='Buyer-generated unique key for this outcome report. An identical retry returns the cached response without another settlement; reuse with a different canonical payload returns IDEMPOTENCY_CONFLICT. Use a fresh UUID v4 for each distinct report.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    purchase_type: Annotated[
        purchase_type_1.PurchaseType | None,
        Field(
            description="The type of financial commitment this outcome is for. Must equal the original approved intent's purchase_type. Determines which budget allocation (if any) to charge against. Defaults to 'media_buy' when omitted."
        ),
    ] = purchase_type_1.PurchaseType.media_buy
    outcome: Annotated[outcome_type.OutcomeType, Field(description='Outcome type.')]
    seller_response: Annotated[
        SellerResponse | None,
        Field(description="The seller's full response. Required when outcome is 'completed'."),
    ] = None
    delivery: Annotated[
        Delivery | None,
        Field(
            description='Buyer-attributed observation compared with the canonical seller delivery statement identified by check_id. This evidence never overwrites seller evidence or creates a second commitment. A conflict produces an explicit disputed reconciliation state while the operational period is open; the plan owner may close it without asserting final billing truth.'
        ),
    ] = None
    error: Annotated[
        reported_outcome_error.ReportedOutcomeError | None,
        Field(
            description='Buyer-attributed error associated with a failed seller interaction. Required when outcome is failed; classification_source=seller_response_copy preserves what the buyer received without claiming seller-attested provenance.'
        ),
    ] = None
    governance_context: Annotated[
        str | None,
        Field(
            description='Opaque governance context from the check_governance response. Required with check_id for completed and failed outcomes and buyer delivery observations.',
            max_length=4096,
            min_length=1,
            pattern='^[\\x20-\\x7E]+$',
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var check_id : str | None
var context : ContextObject | None
var delivery : Delivery | None
var error : ReportedOutcomeError | None
var ext : ExtensionObject | None
var governance_context : str | None
var idempotency_key : str
var model_config
var outcome : OutcomeType
var plan_id : str
var purchase_type : PurchaseType | None
var seller_response : SellerResponse | None

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 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 Setup (**data: Any)
Expand source code
class Setup(AdcpVersionEnvelope):
    model_config = ConfigDict(extra='allow')
    url: AnyUrl | None = None
    message: str
    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 message : str
var model_config
var url : pydantic.networks.AnyUrl | None

Inherited members

class SyncAccountsRequest (**data: Any)
Expand source code
class SyncAccountsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for at-most-once execution. Natural per-account upsert keys handle resource-level dedup, but the envelope triggers onboarding webhooks, billing setup, and audit events — this key prevents those side effects from firing twice on retry. MUST be unique per (seller, request) pair. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    accounts: Annotated[
        list[Accounts | Accounts1],
        Field(
            description='Per-account sync entries. Each entry uses one of two key shapes: the `account` field (AccountRef) for settings-update mode, or the flat `brand` + `operator` + `billing` trio for provisioning mode. An operator_identity settings update MUST carry the latest account revision.',
            max_length=1000,
        ),
    ]
    delete_missing: Annotated[
        StrictBool | None,
        Field(
            description='When true, accounts previously synced by this agent but not included in this request will be deactivated. Scoped to the authenticated agent — does not affect accounts managed by other agents. Use with caution.'
        ),
    ] = False
    dry_run: Annotated[
        StrictBool | None,
        Field(
            description='When true, preview what would change without applying. Returns what would be created/updated/deactivated.'
        ),
    ] = False
    push_notification_config: Annotated[
        push_notification_config_1.PushNotificationConfig | None,
        Field(
            description='Webhook for async notifications when account status changes (e.g., pending_approval transitions to active).'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var accounts : list[Accounts | Accounts1]
var context : ContextObject | None
var delete_missing : bool | None
var dry_run : bool | None
var ext : ExtensionObject | None
var idempotency_key : str
var model_config
var push_notification_config : PushNotificationConfig | None

Inherited members

class SyncCatalogsRequest (**data: Any)
Expand source code
class SyncCatalogsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for at-most-once execution. Catalog upserts and item availability transitions can emit audit events or trigger platform work — this key prevents those side effects from firing twice on retry. Also serves as a request ID on discovery-only calls. MUST be unique per (seller, request) pair. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    account: Annotated[
        account_ref.AccountReference,
        Field(description='Seller account containing these buyer-managed catalogs.'),
    ]
    catalogs: Annotated[
        list[catalog.Catalog] | None,
        Field(
            description='Array of catalog feeds to sync (create or update). When omitted together with item_availability_updates and item_availability_queries, the call is discovery-only and returns all existing catalogs on the account without modification.',
            max_length=50,
            min_length=1,
        ),
    ] = None
    item_availability_updates: Annotated[
        list[catalog_item_availability_update.CatalogItemAvailabilityUpdate] | None,
        Field(
            description='Immediate suppress or restore operations for items in buyer-managed catalogs. Sellers declaring media_buy.features.catalog_item_availability_updates MUST process these updates synchronously and MUST NOT silently ignore them or return a submitted task. A seller that does not declare the capability MUST reject the request with UNSUPPORTED_FEATURE before lookup or mutation and MUST NOT interpret it as discovery. The combined number of item_availability_updates and item_availability_queries MUST NOT exceed 1,000; excess entries are an operation-level INVALID_REQUEST before lookup or mutation. Each (catalog_id, catalog_generation, item_id) tuple MUST appear at most once in updates; a duplicate is an operation-level INVALID_REQUEST before mutation in every validation mode. For mixed catalog/update requests, the seller MUST validate and stage the entire request against the post-upsert candidate state, then commit catalog and availability changes atomically. It MUST reject before any mutation if synchronous atomic commit is unavailable. A successful suppress acknowledgement means the seller MUST stop selecting or rendering the item and every cached or pre-generated creative it materialized from the item. Seller-internal generation lineage MUST retain resolved_account_id, catalog_id, catalog_generation, and item_id. If the seller cannot enforce that guarantee, it MUST return a failed per-item result. Suppression persists across scheduled feed fetches and catalog upserts until explicit restore, expires_at, or deletion of the containing catalog. Restore removes only an existing buyer-authored overlay or tombstone in the same catalog generation and cannot override seller rejection, withdrawal, policy, rights, or inventory controls. A restore for an absent item without such prior state fails with REFERENCE_NOT_FOUND.',
            max_length=1000,
            min_length=1,
        ),
    ] = None
    item_availability_queries: Annotated[
        list[catalog_item_availability_ref.CatalogItemAvailabilityReference] | None,
        Field(
            description='Read current buyer-authored availability state. Queries require media_buy.features.catalog_item_availability_updates; a seller that does not declare it rejects with UNSUPPORTED_FEATURE before lookup. Any request containing queries is synchronous. In a mixed request the seller validates and stages catalog upserts and availability updates first, evaluates queries against that post-upsert/post-update candidate state, and atomically commits the staged mutations before returning those query results. If the mixed work cannot commit synchronously, it rejects before mutation. The seller returns exactly one item_availability_states entry per query in the same order and echoes request_index and the complete identity. Unknown, inaccessible, stale-generation, and unauthorized references use the normalized REFERENCE_NOT_FOUND shape described by validation_mode. Use a fresh idempotency_key for a current read; a replayed response is a historical snapshot.',
            max_length=1000,
            min_length=1,
        ),
    ] = None
    catalog_ids: Annotated[
        list[str] | None,
        Field(
            description='Optional filter to limit sync scope to specific catalog IDs. When provided, only these catalogs will be created/updated. Other catalogs on the account are unaffected.',
            max_length=50,
            min_length=1,
        ),
    ] = None
    delete_missing: Annotated[
        StrictBool | None,
        Field(
            description='When true, buyer-managed catalogs on the account not included in this sync will be removed. Does not affect seller-managed catalogs. Requires catalogs; item_availability_updates alone cannot define deletion scope.'
        ),
    ] = False
    dry_run: Annotated[
        StrictBool | None,
        Field(
            description='When true, preview catalog create, update, and delete changes without applying them. MUST NOT be combined with item_availability_updates.'
        ),
    ] = False
    validation_mode: Annotated[
        validation_mode_1.ValidationMode | None,
        Field(
            description="Validation strictness for semantically valid-looking catalog and item entries. In strict mode (default), an unknown, inaccessible, unauthorized, or stale-generation catalog/item reference, a known seller-managed catalog, a stale expected_overlay_revision, or another per-entry error fails the entire operation before any catalog or availability mutation. In lenient mode, the seller returns a positionally matched failed result for each such item entry and processes the remaining valid entries. Unknown, inaccessible, unauthorized, and stale-generation references MUST be observationally equivalent: code REFERENCE_NOT_FOUND, message exactly 'Catalog item not found', recovery 'correctable', and no field, suggestion, retry_after, issues, details, or resource metadata. Authorization and lookup MUST use the same externally observable failure path and SHOULD avoid materially distinguishable timing. A known seller-managed catalog may use INVALID_REQUEST only after catalog access is authorized. Request-schema failures, duplicate identity tuples, unsupported capability, batch-limit excess, dry_run conflicts, and mixed requests that cannot commit synchronously and atomically are operation-level failures before lookup or mutation in both modes. A stale revision uses CONFLICT without mutation."
        ),
    ] = validation_mode_1.ValidationMode.strict
    push_notification_config: Annotated[
        push_notification_config_1.PushNotificationConfig | None,
        Field(
            description='Optional webhook configuration for async sync notifications. Publisher will send webhook when sync completes if operation takes longer than immediate response time (common for large feeds requiring platform review).'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2
var catalog_ids : list[str] | None
var catalogs : list[Catalog] | None
var context : ContextObject | None
var delete_missing : bool | None
var dry_run : bool | None
var ext : ExtensionObject | None
var idempotency_key : str
var item_availability_queries : list[CatalogItemAvailabilityReference] | None
var item_availability_updates : list[CatalogItemAvailabilityUpdate] | None
var model_config
var push_notification_config : PushNotificationConfig | None
var validation_mode : ValidationMode | None

Inherited members

class SyncGovernanceRequest (**data: Any)
Expand source code
class SyncGovernanceRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for at-most-once execution. `account` gives resource-level dedup, but governance changes emit audit events and can trigger reapproval flows — this key prevents those side effects from firing twice on retry. MUST be unique per (seller, request) pair. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    accounts: Annotated[
        list[Account],
        Field(
            description='Per-account governance agent configuration. Each entry pairs an account reference with the governance agents for that account.',
            max_length=100,
            min_length=1,
        ),
    ]
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var accounts : list[Account]
var context : ContextObject | None
var ext : ExtensionObject | None
var idempotency_key : str
var model_config

Inherited members

class UpdateContentStandardsRequest (**data: Any)
Expand source code
class UpdateContentStandardsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    standards_id: Annotated[str, Field(description='ID of the standards configuration to update')]
    scope: Annotated[
        Scope | None,
        Field(description='Updated scope for where this standards configuration applies'),
    ] = None
    registry_policy_ids: Annotated[
        list[str] | None,
        Field(
            description='Registry policy IDs to use as the evaluation basis. When provided, the agent resolves policies from the registry and uses their policy text and exemplars as the evaluation criteria.'
        ),
    ] = None
    policies: Annotated[
        list[policy_entry.PolicyEntry] | None,
        Field(
            description='Updated bespoke policies for this content-standards configuration, using the same shape as registry entries. Replaces the existing policies array; use stable policy_ids to track policies across versions. Combines with registry_policy_ids. Bespoke policy_ids MUST be flat (no colons/slashes).',
            min_length=1,
        ),
    ] = None
    calibration_exemplars: Annotated[
        CalibrationExemplars | None,
        Field(
            description='Updated training/test set to calibrate policy interpretation. Use URL references for pages to be fetched and analyzed, or full artifacts for pre-extracted content.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for at-most-once execution. If a request with the same key has already been processed, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]

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

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

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

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

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

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

Ancestors

Class variables

var calibration_exemplars : CalibrationExemplars | None
var context : ContextObject | None
var ext : ExtensionObject | None
var idempotency_key : str
var model_config
var policies : list[PolicyEntry] | None
var registry_policy_ids : list[str] | None
var scope : Scope | None
var standards_id : str

Inherited members

class UpdatePropertyListRequest (**data: Any)
Expand source code
class UpdatePropertyListRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    list_id: Annotated[str, Field(description='ID of the property list to update')]
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account that owns the list. Required when the authenticated agent has access to multiple accounts; optional otherwise.'
        ),
    ] = None
    name: Annotated[str | None, Field(description='New name for the list')] = None
    description: Annotated[str | None, Field(description='New description')] = None
    base_properties: Annotated[
        list[base_property_source.BasePropertySource] | None,
        Field(
            description='Complete replacement for the base properties list (not a patch). Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers).'
        ),
    ] = None
    filters: Annotated[
        property_list_filters.PropertyListFilters | None,
        Field(description='Complete replacement for the filters (not a patch)'),
    ] = None
    brand: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description='Update brand reference. Resolved to full brand identity at execution time.'
        ),
    ] = None
    webhook_url: Annotated[
        AnyUrl | None,
        Field(
            description='Update the webhook URL for list change notifications (set to empty string to remove)'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for at-most-once execution. If a request with the same key has already been processed, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]

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

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

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

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

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

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

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var base_properties : list[BasePropertySource1 | BasePropertySource2 | BasePropertySource3] | None
var brand : BrandReference | None
var context : ContextObject | None
var description : str | None
var ext : ExtensionObject | None
var filters : PropertyListFilters | None
var idempotency_key : str
var list_id : str
var model_config
var name : str | None
var webhook_url : pydantic.networks.AnyUrl | None

Inherited members

class ValidateContentDeliveryRequest (**data: Any)
Expand source code
class ValidateContentDeliveryRequest(AdcpRequest, AdcpVersionEnvelope):
    standards_id: Annotated[str, Field(description='Standards configuration to validate against')]
    records: Annotated[
        list[Record],
        Field(
            description='Delivery records to validate (max 10,000)', max_length=10000, min_length=1
        ),
    ]
    feature_ids: Annotated[
        list[str] | None,
        Field(description='Specific features to evaluate (defaults to all)', min_length=1),
    ] = None
    include_passed: Annotated[
        StrictBool | None, Field(description='Include passed records in results')
    ] = True
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

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

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

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

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

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

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

Ancestors

Class variables

var context : ContextObject | None
var ext : ExtensionObject | None
var feature_ids : list[str] | None
var include_passed : bool | None
var model_config
var records : list[Record]
var standards_id : str

Inherited members