Module adcp.decisioning.capabilities

Capability sub-models for declaring :class:DecisioningCapabilities.

The canonical adopter-facing namespace for typed capability declarations. Mirrors the AdCP get_adcp_capabilities response wire schema 1:1 — every sub-model name in this module matches the wire field type it populates.

Typical usage::

from adcp.decisioning import DecisioningCapabilities, DecisioningPlatform
from adcp.decisioning.capabilities import (
    Account, MediaBuy, Targeting, GeoMetros,
    IdempotencySupported, Specialism,
)

class HelloSeller(DecisioningPlatform):
    capabilities = DecisioningCapabilities(
        specialisms=[Specialism.sales_non_guaranteed],
        adcp=Adcp(
            major_versions=[3],
            idempotency=IdempotencySupported(
                supported=True, replay_ttl_seconds=86400,
            ),
        ),
        account=Account(supported_billing=["operator"]),
        media_buy=MediaBuy(
            supported_pricing_models=["cpm"],
            execution=Execution(
                targeting=Targeting(
                    geo_countries=True,
                    geo_metros=GeoMetros(nielsen_dma=True),
                ),
            ),
        ),
    )

The names Account, MediaBuy, Creative collide with unrelated wire types in :mod:adcp.types. This submodule re-aliases the disambiguated forms (CapabilitiesAccount etc. in :mod:adcp.types.capabilities) back to the wire-spec names within its own namespace, so adopter code reads cleanly against the spec.

Classes

class A2ui (**data: Any)
Expand source code
class A2ui(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    supported: Annotated[
        StrictBool | None, Field(description='Supports A2UI surface rendering')
    ] = False
    catalogs: Annotated[
        list[str] | None,
        Field(description="Supported A2UI component catalogs (e.g., 'si-standard', 'standard')"),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var catalogs : list[str] | None
var model_config
var supported : bool | None

Inherited members

class Account (**data: Any)
Expand source code
class Account(AdCPBaseModel):
    require_operator_auth: Annotated[
        StrictBool | None,
        Field(
            description="Whether the seller requires operator-level credentials. This declares who must authenticate; it does not by itself declare whether OAuth is used, whether list_accounts is exposed, or which sync_accounts modes are supported. When true, operators authenticate independently with the seller and account-scoped calls use seller/storefront-assigned account_id values because the seller or upstream platform owns the canonical account namespace. If a credential may access more than one account, the seller MUST expose list_accounts and buyers MUST resolve an explicit account_id before the first account-scoped request. If a credential is bound to exactly one account, the seller SHOULD expose list_accounts returning that singleton; a seller MAY omit list_accounts only when it provides the same explicit account_id through another declared path or out-of-band onboarding. When false (default, buyer-declared accounts), the seller trusts the agent's identity claims and account-scoped calls use the advertiser natural key: brand + operator + optional operator_unit, fixed currency, optional buyer-selected account timezone, and sandbox. operator_unit.id is owned by the operator and is distinct from the seller's account_id. The seller normally provisions through sync_accounts, but MAY lazily provision on the first account-scoped request when billing and other required settings are unambiguous from capabilities or onboarding defaults. A lazy-provisioning seller MUST keep accepting the natural key and MUST expose list_accounts for recovery; if buyer input is needed before use, the seller MUST expose sync_accounts."
        ),
    ] = False
    authorization_endpoint: Annotated[
        AnyUrl | None,
        Field(
            description='OAuth authorization endpoint for obtaining operator-level credentials. Present when the seller supports OAuth for operator authentication. The agent directs the operator to this URL to authenticate and obtain a bearer token. If absent and require_operator_auth is true, operators obtain credentials out-of-band (e.g., seller portal, API key).'
        ),
    ] = None
    supported_billing: Annotated[
        list[SupportedBillingEnum],
        Field(
            description="Billing models this seller supports. operator: seller invoices the operator (agency or brand buying direct). agent: agent consolidates billing. advertiser: seller invoices the advertiser directly, even when a different operator places orders on their behalf. When the buyer calls sync_accounts, it must pass one of these values. A lazy-provisioning seller may omit sync_accounts only when billing can be resolved unambiguously from this capability or the authenticated agent's onboarding defaults.",
            min_length=1,
        ),
    ]
    supported_account_currency_modes: Annotated[
        list[SupportedAccountCurrencyMode] | None,
        Field(
            description='Required for sellers implementing AdCP 3.2 advertiser-account provisioning, but optional in this shared 3.x response schema so existing 3.0 and 3.1 capability responses remain valid. Declares whether advertiser accounts are bound to one immutable currency (`fixed`), select currency independently per proposal or media buy (`per_media_buy`), or support both models. When only `fixed` is advertised, buyer-declared provisioning entries MUST include `currency`. When only `per_media_buy` is advertised, they MUST omit it. When both are advertised, presence of `currency` selects a fixed-currency account and omission selects per-media-buy currency. Buyers MUST treat absence as an older seller whose currency mode is not discoverable, not as support for either mode.',
            min_length=1,
        ),
    ] = None
    timezone: Annotated[
        Timezone | None,
        Field(
            description='Required for sellers implementing AdCP 3.2 advertiser-account provisioning, but optional in the shared 3.x response schema for compatibility. Declares whether the account timezone is seller-wide or fixed per account and whether a buyer must select it during sync_accounts provisioning. Account timezone is the default for account-scoped calendar semantics; feature-specific capability fields explicitly declare exceptions.',
            title='Account Timezone Capability',
        ),
    ] = None
    required_for_products: Annotated[
        StrictBool | None,
        Field(
            description='Whether an account reference is required for get_products. When true, the buyer must establish an account before browsing products. When false (default), the buyer can browse products without an account — useful for price comparison and discovery before committing to a seller.'
        ),
    ] = False
    account_financials: Annotated[
        StrictBool | None,
        Field(
            description='Whether this seller exposes the `get_account_financials` task for querying account-level financial status (spend, credit, invoices). Acts as a **pre-call discriminator** — buyers MUST consult this field before issuing `get_account_financials`; when `false` (or absent), sellers MAY reject the call with an `UNSUPPORTED_FEATURE` / `OPERATION_NOT_SUPPORTED` error. Companion pattern to `creative.bills_through_adcp` (issue #2881) — both fields let buyers gate optional capability calls on a single declared boolean rather than probing for support. Only applicable to operator-billed accounts; sellers using buyer-billed flows omit or set to `false`.'
        ),
    ] = False
    notifications: Annotated[
        Notifications6 | Notifications7 | None,
        Field(
            description='Whether the seller supports durable account-lifecycle webhooks through account-level `notification_configs[]`. This capability is specifically for account status changes such as approval, rejection, payment-required, suspension, recovery, and closure. When supported, buyers register subscribers with `sync_accounts.accounts[].notification_configs[]`; each `account.status_changed` fire is an invalidation payload, and buyers repair by re-reading `list_accounts` for the account_id.'
        ),
    ] = None
    change_feed: Annotated[
        ChangeFeed | ChangeFeed3 | None,
        Field(
            description='Whether the seller exposes a durable, ordered feed of material changes to authoritative account-scoped state. This is distinct from webhook_activity transport diagnostics and from current-state reads. Sellers claiming support MUST retain changes for at least 90 days after recording and MUST produce records regardless of whether a mutation originated through AdCP, a seller surface, another authorized principal, seller automation, or a connected platform within declared coverage. Experimental in 3.2 (RFC #6810): sellers advertising supported: true MUST list account.change_feed in experimental_features.'
        ),
    ] = None
    identity_updates: Annotated[
        IdentityUpdates | IdentityUpdates3 | None,
        Field(
            description='Whether the seller accepts buyer-desired operator identity reconciliation through sync_accounts settings-update entries. Sellers declaring support expose the exact identity transitions they implement, MUST return account revisions from sync_accounts and list_accounts, and MUST return identity_change_preview for dry-run identity updates.'
        ),
    ] = None
    sandbox: Annotated[
        StrictBool | None,
        Field(
            description='Whether this seller supports sandbox accounts for testing. Buyer-declared accounts use sandbox: true in sync_accounts or, for an unambiguous lazy-provisioning seller, in the natural-key account reference. Sellers with account_id namespaces expose sandbox accounts as pre-existing test accounts through list_accounts or supply them out-of-band. Requests using a sandbox account perform no real platform calls or spend.'
        ),
    ] = False

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var account_financials : bool | None
var authorization_endpoint : pydantic.networks.AnyUrl | None
var change_feed : ChangeFeed | ChangeFeed3 | None
var identity_updates : IdentityUpdates | IdentityUpdates3 | None
var model_config
var notifications : Notifications6 | Notifications7 | None
var require_operator_auth : bool | None
var required_for_products : bool | None
var sandbox : bool | None
var supported_account_currency_modes : list[SupportedAccountCurrencyMode] | None
var supported_billing : list[SupportedBillingEnum]
var timezone : Timezone | None

Inherited members

class Accreditation (**data: Any)
Expand source code
class Accreditation(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    accrediting_body: Annotated[
        str,
        Field(
            description='Accrediting organization — open string (the global landscape includes MRC, ARF, ABC, BARB, JICWEBS, AGOF, JIC bodies in many markets). Use the canonical short name where one exists.',
            examples=['MRC', 'ARF', 'ABC', 'BARB', 'JICWEBS', 'AGOF'],
        ),
    ]
    certification_id: Annotated[
        str | None,
        Field(
            description="Optional identifier for the certification in the accrediting body's records (when one exists; many bodies do not issue stable IDs)."
        ),
    ] = None
    valid_until: Annotated[
        date | None,
        Field(
            description="Optional ISO 8601 date when the current accreditation expires. Buyers MAY treat post-expiry data as un-accredited. Absence means the vendor does not assert an expiry — buyers SHOULD verify currency at the accrediting body's directory."
        ),
    ] = None
    evidence_url: Annotated[
        AnyUrl | None,
        Field(
            description="Optional URL pointing at the accrediting body's public listing for this certification (the buyer's path to verify the claim independently)."
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var accrediting_body : str
var certification_id : str | None
var evidence_url : pydantic.networks.AnyUrl | None
var model_config
var valid_until : datetime.date | None

Inherited members

class Adcp (**data: Any)
Expand source code
class Adcp(AdCPBaseModel):
    major_versions: Annotated[
        list[MajorVersion],
        Field(
            deprecated=True,
            description='DEPRECATED in favor of `supported_versions` (release-precision strings). Servers MUST continue to emit this field through 3.x for backwards compatibility. Removed in 4.0. Original semantics: AdCP major versions supported by this seller. Major versions indicate breaking changes.',
            min_length=1,
        ),
    ]
    supported_versions: Annotated[
        list[SupportedVersion] | None,
        Field(
            description='Release-precision (VERSION.RELEASE) AdCP versions this seller speaks. Authoritative for buyer-side release pinning — buyers SHOULD declare `adcp_version` (release-precision string) on each request. Sellers downshift to the highest supported release ≤ the buyer\'s pin within the same major; cross-major mismatch returns VERSION_UNSUPPORTED. Pre-release tags (e.g. `"3.1-beta"`) hang off release.',
            examples=[['3.0'], ['3.0', '3.1'], ['3.0', '3.1-beta']],
            min_length=1,
        ),
    ] = None
    build_version: Annotated[
        str | None,
        Field(
            description="Optional advisory metadata: full semver build identifier of the seller's deployment — MAJOR.MINOR.PATCH plus optional pre-release and build-metadata segments per semver §9–§10. Patches are not part of the wire contract — semver patch by definition introduces no contract change — but surfacing the build helps buyers triage incidents and bug reports against a specific seller deployment lineage. Buyers MUST NOT use this field for negotiation; use `supported_versions` (release-precision) instead.",
            examples=[
                '3.0.1',
                '3.1.2',
                '3.1.0-beta.3',
                '3.1.2+scope3.deploy.4821',
                '3.1.0-beta.3+sha.a1b2c3d',
            ],
            pattern='^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$',
        ),
    ] = None
    idempotency: Annotated[
        Idempotency | Idempotency3,
        Field(
            description='Idempotency semantics for mutating requests. Sellers MUST declare whether they honor idempotency_key replay protection so buyers can reason about safe retry behavior. Modeled as a discriminated union on the supported boolean so that code generators produce two named types (IdempotencySupported, IdempotencyUnsupported) with the replay_ttl_seconds invariant enforced at the type level — draft-07 if/then would be dropped by most generators (openapi-typescript, zod-to-json-schema, datamodel-code-generator pre-0.25, quicktype). Clients MUST NOT assume a default — a seller without this declaration is non-compliant and should be treated as unsafe for retry-sensitive operations.'
        ),
    ]
    principal: Annotated[
        Principal | None,
        Field(
            description='Caller-scoped durable connection configuration accepted by this agent. This is the buyer-to-seller configuration half of negotiation, not a second seller capability document: the seller advertises its objective offering here, while each authenticated caller submits its desired webhooks and reusable destinations through sync_principal and reads them back through get_principal. Per-account authority and feed selection remain in account/reporting configuration. Sellers exposing this block MUST list protocol.principal in experimental_features.'
        ),
    ] = None
    capability_changes: Annotated[
        CapabilityChanges | None,
        Field(
            description='Freshness metadata and optional invalidation webhooks for this `get_adcp_capabilities` document. Buyers and registries MAY cache capabilities for up to `cache_ttl_seconds` when present, SHOULD compare `capabilities_version` across refreshes when present, and SHOULD re-run `get_adcp_capabilities` after receiving a `capabilities.changed` webhook. This block describes the agent-wide capability document, not per-caller authorization or account-scoped settings. A material capability change is any externally advertised contract change that can affect routing, validation, conformance coverage, task availability, auth/account handling, sandbox support, billing support, reporting delivery methods, creative-library support, targeting support, protocol versions, or other buyer-visible feature gates. Non-contract operational changes that do not alter the response body do not require a revision or webhook fire.'
        ),
    ] = None
    governance_enforcement: Annotated[
        GovernanceEnforcement | None,
        Field(
            description='Cross-role declaration that this agent enforces buyer-provided governance authorization when performing consequential tasks. This is distinct from the top-level `governance` capability block, which describes an agent that provides governance services. An agent can enforce governance without implementing the governance protocol itself. Absence means the agent makes no governance-enforcement conformance claim.'
        ),
    ] = None
    attestations: Annotated[
        Attestations | None,
        Field(
            description='Portable-attestation trust and delivery capabilities for this evaluator. Present only when the agent accepts AttestationReference inputs on one or more domain task surfaces. This block is an allowlist: presenters cannot expand accepted issuers, resolver endpoints, verifier agents, claim types, or proof formats by supplying values in a request.',
            examples=[
                {
                    'accepted_claim_types': [
                        'https://claims.example/audience/methodology-reviewed'
                    ],
                    'accepted_proof_formats': ['https://www.w3.org/TR/vc-jose-cose/'],
                    'supported_delivery_methods': ['issuer_credential_id', 'embedded'],
                    'accepted_issuers': [
                        {
                            'issuer': {'type': 'origin', 'origin': 'https://credentials.example'},
                            'resolvers': [
                                {
                                    'resolver_id': 'primary',
                                    'url': 'https://resolver.credentials.example/v1/credentials',
                                    'authentication': 'evaluator_managed',
                                }
                            ],
                        }
                    ],
                    'max_embedded_credential_bytes': 262144,
                }
            ],
            title='Attestation Capabilities',
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var attestations : Attestations | None
var build_version : str | None
var capability_changes : CapabilityChanges | None
var governance_enforcement : GovernanceEnforcement | None
var idempotency : Idempotency | Idempotency3
var major_versions : list[MajorVersion]
var model_config
var principal : Principal | None
var supported_versions : list[SupportedVersion] | None

Inherited members

class AgeRestriction (**data: Any)
Expand source code
class AgeRestriction(AdCPBaseModel):
    supported: Annotated[
        StrictBool | None, Field(description='Whether seller supports age restrictions')
    ] = None
    verification_methods: Annotated[
        list[VerificationMethod] | None,
        Field(description='Age verification methods this seller supports'),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var supported : bool | None
var verification_methods : list[VerificationMethod] | None

Inherited members

class AttributionWindow (**data: Any)
Expand source code
class AttributionWindow(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    event_type: EventType | None = None
    post_click: Annotated[
        list[PostClickItem],
        Field(
            description='Available post-click attribution windows (e.g. [{"interval": 7, "unit": "days"}])',
            min_length=1,
        ),
    ]
    post_view: Annotated[
        list[PostViewItem] | None,
        Field(
            description='Available post-view attribution windows (e.g. [{"interval": 1, "unit": "days"}])',
            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 event_type : EventType | None
var model_config
var post_click : list[PostClickItem]
var post_view : list[PostViewItem] | None

Inherited members

class AudienceTargeting (**data: Any)
Expand source code
class AudienceTargeting(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    supported_identifier_types: Annotated[
        list[SupportedIdentifierType],
        Field(
            description='PII-derived identifier types accepted for audience matching. Buyers should only send identifiers the seller supports.',
            min_length=1,
        ),
    ]
    supports_platform_customer_id: Annotated[
        StrictBool | None,
        Field(
            description="Whether the seller accepts the buyer's CRM/loyalty ID as a matchable identifier. Only applicable when the seller operates a closed ecosystem with a shared ID namespace (e.g., a retailer matching against their loyalty program). When true, buyers can include platform_customer_id values in AudienceMember.identifiers for matching against the seller's identity graph. Reporting on matched platform_customer_ids typically requires a clean room or the seller's own reporting surface."
        ),
    ] = None
    supported_uid_types: Annotated[
        list[UIDType] | None,
        Field(
            description='Universal ID types accepted for audience matching (MAIDs, RampID, UID2, etc.). MAID support varies significantly by platform — check this field before sending uids with type: maid.',
            min_length=1,
        ),
    ] = None
    minimum_audience_size: Annotated[
        SchemaInt,
        Field(
            description='Minimum matched audience size required for targeting. Audiences below this threshold will have status: too_small. Varies by platform (100–1000 is typical).',
            ge=1,
        ),
    ]
    supported_activation_methods: Annotated[
        list[
            SupportedActivationMethods
            | SupportedActivationMethods1
            | SupportedActivationMethods2
            | SupportedActivationMethods3
            | SupportedActivationMethods4
            | SupportedActivationMethods5
        ]
        | None,
        Field(
            description="Union of audience_activation.methods across the seller's products. Fast-fail discovery: a buyer reads this once and skips the catalog walk when nothing overlaps its pipeline. Per-product declarations are the source of truth; sellers MUST keep this consistent with the catalog. Operational coordinates are account-scoped: the union MAY omit consumer_identities and destination_ref until bilateral account setup establishes them, and MUST NOT expose another account's coordinates. Absence of this field with media_buy.audience_activation listed in experimental_features means walk the catalog; only a present, non-overlapping union is a fast-fail signal. Experimental (x-status: experimental): sellers implementing audience activation declarations MUST list media_buy.audience_activation in experimental_features. Per docs/reference/experimental-status, this surface MAY change between 3.x releases with notice.",
            min_length=1,
        ),
    ] = None
    matching_latency_hours: Annotated[
        MatchingLatencyHours | None,
        Field(
            description='Expected matching latency range in hours after upload. Use to calibrate polling cadence and set appropriate expectations before configuring push_notification_config.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var matching_latency_hours : MatchingLatencyHours | None
var minimum_audience_size : int
var model_config
var supported_activation_methods : list[SupportedActivationMethods | SupportedActivationMethods1 | SupportedActivationMethods2 | SupportedActivationMethods3 | SupportedActivationMethods4 | SupportedActivationMethods5] | None
var supported_identifier_types : list[SupportedIdentifierType]
var supported_uid_types : list[UIDType] | None
var supports_platform_customer_id : bool | None

Inherited members

class Avatar (**data: Any)
Expand source code
class Avatar(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    provider: Annotated[
        str | None, Field(description='Avatar provider (d-id, heygen, synthesia, etc.)')
    ] = None
    avatar_id: Annotated[str | None, Field(description='Brand avatar identifier')] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var avatar_id : str | None
var model_config
var provider : str | None

Inherited members

class Brand (**data: Any)
Expand source code
class Brand(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    rights: Annotated[
        StrictBool | None,
        Field(
            description='Supports get_rights and acquire_rights for rights discovery and clearance'
        ),
    ] = False
    right_types: Annotated[
        list[RightType] | None, Field(description='Types of rights available through this agent')
    ] = None
    available_uses: Annotated[
        list[AvailableUs] | None,
        Field(description="Rights uses available across this agent's roster"),
    ] = None
    generation_providers: Annotated[
        list[str] | None,
        Field(description='LLM/generation providers this agent can issue credentials for'),
    ] = None
    description: Annotated[
        str | None,
        Field(
            description="Description of the agent's brand protocol capabilities", max_length=5000
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

Raises [ValidationError][pydantic_core.ValidationError] if the input data 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_uses : list[AvailableUs] | None
var description : str | None
var generation_providers : list[str] | None
var model_config
var right_types : list[RightType] | None
var rights : bool | None

Inherited members

class SiCapabilities (**data: Any)
Expand source code
class Capabilities(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    modalities: Annotated[
        Modalities | None, Field(description='Interaction modalities supported')
    ] = None
    components: Annotated[Components | None, Field(description='Visual components supported')] = (
        None
    )
    commerce: Annotated[Commerce | None, Field(description='Commerce capabilities')] = None
    a2ui: Annotated[A2ui | None, Field(description='A2UI (Agent-to-UI) capabilities')] = None
    mcp_apps: Annotated[
        StrictBool | None,
        Field(description='Supports MCP Apps for rendering A2UI surfaces in iframes'),
    ] = False

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var a2ui : A2ui | None
var commerce : Commerce | None
var components : Components | None
var mcp_apps : bool | None
var modalities : Modalities | None
var model_config

Inherited members

class Commerce (**data: Any)
Expand source code
class Commerce(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    acp_checkout: Annotated[
        StrictBool | None,
        Field(description='Supports ACP (Agentic Commerce Protocol) checkout handoff'),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var acp_checkout : bool | None
var model_config

Inherited members

class ComplianceTesting (**data: Any)
Expand source code
class ComplianceTesting(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    scenarios: Annotated[
        list[str],
        Field(
            description="Compliance testing scenarios this agent supports. Must be non-empty — at least one scenario. Values SHOULD include every canonical controller scenario the agent implements, excluding list_scenarios because that value is a discovery operation rather than a test capability. Values MAY also include implementation-specific scenarios. Callers can use comply_test_controller with scenario: 'list_scenarios' to discover supported scenarios at runtime.",
            min_length=1,
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var scenarios : list[str]

Inherited members

class Components (**data: Any)
Expand source code
class Components(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    standard: Annotated[
        list[StandardEnum] | None,
        Field(description='Standard components that all SI hosts must render'),
    ] = None
    extensions: Annotated[
        dict[str, Any] | None,
        Field(description='Platform-specific extensions (chatgpt_apps_sdk, maps, forms, etc.)'),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var extensions : dict[str, typing.Any] | None
var model_config
var standard : list[StandardEnum] | None

Inherited members

class CompromiseNotification (**data: Any)
Expand source code
class CompromiseNotification(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    emits: Annotated[
        StrictBool | None,
        Field(description='Whether this agent emits `identity.compromise_notification` events.'),
    ] = False
    accepts: Annotated[
        StrictBool | None,
        Field(
            description='Whether this agent subscribes to `identity.compromise_notification` events from counterparties it verifies signatures from.'
        ),
    ] = False

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var accepts : bool | None
var emits : bool | None
var model_config

Inherited members

class ContentStandards (**data: Any)
Expand source code
class ContentStandards(AdCPBaseModel):
    supports_local_evaluation: Annotated[
        StrictBool | None,
        Field(
            description="Whether the seller runs a local evaluation model. When false, all artifacts will have local_verdict: 'unevaluated' and the failures_only filter on get_media_buy_artifacts is not useful."
        ),
    ] = None
    supported_channels: Annotated[
        list[MediaChannel] | None,
        Field(
            description='Channels for which the seller can provide content artifacts. Helps buyers understand which parts of a mixed-channel buy will have content standards coverage.',
            min_length=1,
        ),
    ] = None
    supports_webhook_delivery: Annotated[
        StrictBool | None,
        Field(
            description='Whether the seller supports push-based artifact delivery via artifact_webhook configured at buy creation time.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var supported_channels : list[MediaChannel] | None
var supports_local_evaluation : bool | None
var supports_webhook_delivery : bool | None

Inherited members

class ConversionTracking (**data: Any)
Expand source code
class ConversionTracking(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    multi_source_event_dedup: Annotated[
        StrictBool | None,
        Field(
            description='Whether this seller can deduplicate conversion events across multiple event sources within a single goal. When true, the seller honors the deduplication semantics in optimization_goals event_sources arrays — the same event_id from multiple sources counts once. When false or absent, buyers should use a single event source per goal; multi-source arrays will be treated as first-source-wins. Most social platforms cannot deduplicate across independently-managed pixel and CAPI sources.'
        ),
    ] = None
    per_creative_attribution: Annotated[
        StrictBool | None,
        Field(
            description='Whether the seller can attribute conversions to specific creatives within a package and surface that breakdown via media_buy_deliveries[].by_package[].by_creative[].conversions in get_media_buy_delivery. Defaults to false when omitted. Sellers that report conversions only at the line / package / placement / campaign granularity (retail-media, MMP-mediated mobile, CTV performance) declare false (or omit) and the per-creative scenario grades not_applicable for them. Sellers that surface ad-level conversion attribution (most social platforms) declare true and the scenario asserts the breakdown is populated end-to-end. Defaults to false to preserve backward compatibility.'
        ),
    ] = None
    supported_event_types: Annotated[
        list[EventType] | None,
        Field(
            description='Event types this seller can track and attribute. If omitted, all standard event types are supported.',
            min_length=1,
        ),
    ] = None
    supported_targets: Annotated[
        list[SupportedTarget3] | None,
        Field(
            description='Event-goal target kinds this seller can compute against. Buyers should only submit event-kind optimization goals whose target.kind is listed here — sellers MUST reject goals with unlisted target kinds. When omitted, only target-less event goals (maximize conversion count within budget) are guaranteed; sellers MAY accept specific target kinds but buyers should not rely on it. Named to parallel `metric_optimization.supported_targets` at the product level — same concept (which target kinds are supported), one at seller-capability granularity and one at product granularity.',
            min_length=1,
        ),
    ] = None
    supported_uid_types: Annotated[
        list[UIDType] | None,
        Field(description='Universal ID types accepted for user matching', min_length=1),
    ] = None
    supported_hashed_identifiers: Annotated[
        list[SupportedIdentifierType] | None,
        Field(
            description='Hashed PII types accepted for user matching. Buyers must hash before sending (SHA-256, normalized).',
            min_length=1,
        ),
    ] = None
    supported_action_sources: Annotated[
        list[SupportedActionSource] | None,
        Field(description='Action sources this seller accepts events from', min_length=1),
    ] = None
    attribution_windows: Annotated[
        list[AttributionWindow] | None,
        Field(
            description='Attribution windows available from this seller. Single-element arrays indicate fixed windows; multi-element arrays indicate configurable options the buyer can choose from via attribution_window on optimization goals.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var attribution_windows : list[AttributionWindow] | None
var model_config
var multi_source_event_dedup : bool | None
var per_creative_attribution : bool | None
var supported_action_sources : list[SupportedActionSource] | None
var supported_event_types : list[EventType] | None
var supported_hashed_identifiers : list[SupportedIdentifierType] | None
var supported_targets : list[SupportedTarget3] | None
var supported_uid_types : list[UIDType] | None

Inherited members

class Creative (**data: Any)
Expand source code
class Creative(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    supports_compliance: Annotated[
        StrictBool | None,
        Field(
            description='When true, this creative agent can process briefs with compliance requirements (required_disclosures, prohibited_claims) and will validate that disclosures can be satisfied by the target format.'
        ),
    ] = None
    has_creative_library: Annotated[
        StrictBool | None,
        Field(
            description='When true, this agent hosts a creative library and supports list_creatives and creative_id references in build_creative. Creative agents with a library should also implement the accounts protocol (sync_accounts / list_accounts) so buyers can establish access.'
        ),
    ] = False
    supports_revisions: Annotated[
        StrictBool | None,
        Field(
            description='When true, this agent accepts buyer-assigned revision_id on sync_creatives, enforces immutable revision content, echoes accepted revision identity, returns it from list_creatives, and attributes delivered executions to it. Revision support does not imply revision history, rollback, or staged activation.'
        ),
    ] = False
    supports_generation: Annotated[
        StrictBool | None,
        Field(
            description='When true, this agent can generate creatives from natural language briefs via build_creative. The buyer provides a message with creative direction, and the agent produces a manifest with generated assets. When false, build_creative only supports transformation or library retrieval.'
        ),
    ] = False
    supports_transformation: Annotated[
        StrictBool | None,
        Field(
            description='When true, this agent can transform or resize existing canonical manifests via build_creative. The buyer supplies a creative_manifest and an advertised target_capability_id.'
        ),
    ] = False
    representation_resolution: Annotated[
        RepresentationResolution | None,
        Field(
            description='Explicit opt-in for deterministic seller-bound selection from `build_creative.creative_representation_set`. Only the destination sales agent may advertise and exercise this capability because resolution requires its current product, placement/publisher narrowings, and seller-wide execution ceilings. A standalone creative agent may help a buyer select locally but MUST NOT advertise this capability or claim seller deliverability. Absence means the caller selects a representation before sending a seller-bound manifest; the agent MUST NOT guess silently.'
        ),
    ] = None
    supports_transformers: Annotated[
        StrictBool | None,
        Field(
            description='When true, this agent exposes account-scoped creative transformers via list_transformers (the creative analog of media-buy products) and accepts transformer_id + config on build_creative. Buyers SHOULD call list_transformers to discover available transformers, their typed config params (and account-scoped enumerable option values via expand_params), and pricing. When false or absent, the agent does not offer the transformer surface.'
        ),
    ] = False
    supports_refinement: Annotated[
        StrictBool | None,
        Field(
            description="When true, this agent retains produced build_variant leaves for an agent-defined retention window and can re-build from one via build_creative's refine_from_build_variant_id — applying a natural-language instruction in message plus an optional config delta, returning new lineage-linked variants. A build-time agent capability independent of generation/transformation. When false or absent, refine_from_build_variant_id is rejected with UNSUPPORTED_FEATURE; buyers refine instead via the transform path (creative_manifest + message)."
        ),
    ] = False
    supports_spend_controls: Annotated[
        StrictBool | None,
        Field(
            description='When true, build_creative honors a per-call `max_spend` ceiling (producing partial paid results and returning budget_status:"capped" + a BUDGET_CAP_REACHED advisory rather than overspending) AND supports mode:"estimate" dry-runs (a projected cost band, producing/billing nothing). When false or absent, max_spend / mode:estimate are rejected with UNSUPPORTED_FEATURE. Out-of-band billers (bills_through_adcp:false) have no AdCP cost truth to cap against, so this is meaningful only alongside bills_through_adcp:true.'
        ),
    ] = False
    supports_evaluator: Annotated[
        StrictBool | None,
        Field(
            description="Experimental (x-status: experimental) — agents setting this true MUST also list `creative.evaluator` in `experimental_features`; the surface MAY change between 3.x releases with notice (see docs/reference/experimental-status). When true, build_creative accepts an advisory `evaluator` input (exemplars / account-arranged evaluator_id / agent_url, plus an optional `feature_requirement[]` gate, a `rank_by` ordering, and an allowlisted `feature_agent` pointer). Feature discovery uses this response's governance.creative_features catalog: rank_by, feature_requirement, and eval.features[] all share the same creative-feature vocabulary as get_creative_features. evaluator_id is not discovered from this catalog; it is a pre-provisioned account preset whose emitted feature_ids still come from it. The evaluator populates a per-leaf `eval` block of creative-feature values (creative-feature-result[], the same shape get_creative_features returns) on BuildCreativeVariantSuccess leaves, which is what the recommended/rank it sets on the best_of_n axis are computed over. The agent runs a gate-then-rank pipeline over its best_of_n exploration: it evaluates each leaf, DROPS leaves failing `feature_requirement[]` from its recommended survivors, then orders survivors by `rank_by`. The gate is internal pruning of which leaves the agent recommends/returns from its own exploration — it never blocks an already-produced billable leaf: what is produced and billed is governed by max_variants/max_creatives/max_spend, not the evaluator. When the evaluator names an external agent, it MUST appear in `creative_policy.accepted_verifiers[]` (off-list → EVALUATOR_AGENT_NOT_ACCEPTED), and the producing agent authenticates the outbound evaluator call on the transport. Evaluator credentials and caller-supplied trust material MUST NOT be passed in the build_creative payload; credential- or trust-material payload keys should be rejected with CREDENTIAL_IN_ARGS. When false or absent, the `evaluator` input is ignored and no `eval` block is emitted."
        ),
    ] = False
    refinable_retention_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='When supports_refinement is true, the GUARANTEED-MINIMUM window (a floor, not a ceiling) during which a produced build_variant_id remains refinable via refine_from_build_variant_id: a ref within this window from production SHOULD resolve; the agent MAY retain longer. Omit when the retention window is agent-defined and not advertised — buyers then treat refinability as best-effort and handle REFERENCE_NOT_FOUND.',
            ge=0,
        ),
    ] = None
    multiplicity: Annotated[
        Multiplicity | None,
        Field(
            description="Pre-call discriminators for build_creative fan-out, so a buyer knows BEFORE sending max_creatives / max_variants whether this agent supports them and the ceilings. Over-limit requests are CLAMPED to these ceilings (the agent produces up to the limit and signals the shortfall via items_returned < items_total on BuildCreativeVariantSuccess), not rejected — consistent with item_limit's 'use the lesser' rule. Absent means no fan-out: build_creative produces a single creative and max_creatives/max_variants>1 are not supported."
        ),
    ] = None
    supported_formats: Annotated[
        list[SupportedFormat] | None,
        Field(
            description='Canonical-format capability catalog for this creative agent. This is the 3.2 source of truth for discovering which format contracts the agent can build, validate, or preview; it replaces the deprecated `list_creative_formats` task. Each entry uses the authority-free `CreativeOperationFormatDeclaration` projection of a product format declaration: canonical shape and creative-route macro processing are preserved, while seller production commitments are excluded. New 3.2 producers MUST publish a stable agent-local `capability_id` and explicit `operations` for task routing. Every emitted `capability_id` MUST be unique within this catalog so a route selects exactly one entry. During the 3.x compatibility window, consumers MUST also accept legacy entries that omit either field; absent `operations` means `["build"]`, while an absent `capability_id` means the entry is discoverable by canonical contract but cannot be selected through a capability-ID route.\n\n**Publisher-specific support.** To claim exact support for a publisher declaration, `format` carries the declaration\'s `{publisher_domain, format_option_id}` pair plus its canonical `format_kind` and narrowed `params`. Generic creative agents MAY instead advertise a canonical parameter envelope without publisher identity. A generic capability matches a target declaration only when the capability can satisfy every target constraint; matching canonical names alone is insufficient. Registries MAY reverse-index these entries by `format.format_kind`, `format.publisher_domain`, and `format.format_option_id`.\n\nThis catalog describes creative operations, not sales-agent inventory deliverability. Sales agents publish the purchasable closed set on each `Product.format_options[]`; publisher acceptance lives in `adagents.json.formats[]`.'
        ),
    ] = None
    preview: Annotated[
        Preview | None,
        Field(
            description='Per-route preview_creative capability metadata. New 3.2 producers whose supported_formats[] explicitly advertises a routable preview operation MUST emit this block. rendering_origin describes how each route is implemented but is informational and never grants presentation authority: only a matching publisher-origin placement preview_provider delegation can do that. routes[].capability_id MUST equal the set of capability IDs on supported_formats[] entries whose operations contains preview.'
        ),
    ] = None
    localization: Annotated[
        Localization | None,
        Field(
            description='Materialized creative-localization support for sync_creatives/list_creatives, including source-only monolingual topology. Presence opts the agent into exact locale-variant round-trip, strict RFC 4647 Lookup, optional buyer-declared language-family fallback rules, explicit final default/unmatched behavior, creative-wide review, transactional replacement, seller product-format locale-policy enforcement, and delivery attribution. This is a coarse structural capability, not a promise that every locale/format/account combination is accepted; sellers publish accepted ranges on product format declarations and validate each write before mutation. Omit this object when localization is unsupported.'
        ),
    ] = None
    bills_through_adcp: Annotated[
        StrictBool | None,
        Field(
            description='When true, this creative agent bills through the AdCP rate-card surface: list_creatives returns pricing_options when include_pricing=true with an authenticated account, build_creative populates pricing_option_id and vendor_cost on the response, and report_usage accepts records against the rate card. When false or absent, the agent bills out of band (flat license, SaaS contract, bundled enterprise agreement) and buyers should skip pricing fields and tolerate report_usage returning accepted: 0 with errors carrying BILLING_OUT_OF_BAND. A pre-call discriminator so buyer agents can route across many creative agents without first establishing an account to probe pricing.'
        ),
    ] = False
    canonical_catalog_version: Annotated[
        str | None,
        Field(
            description="Optional. The AdCP canonical-formats catalog version this agent's runtime is built against (e.g., `3.1`, `3.2.0`). Lets buyer SDKs detect canonical-catalog skew between their generated types and the seller's actual support. SDKs MAY declare the version they were generated against (typically the AdCP version they ship for); when seller and SDK versions disagree, SDKs SHOULD soft-warn rather than fail (the open-enum semantics on `canonical-format-kind.json` make unknown canonicals safe to retain, so skew is not a hard error — it just means the older side might not understand newer canonical values). Omitted by sellers who haven't yet generated against a versioned catalog; absence is interpreted as the AdCP version advertised by the broader capabilities response.",
            pattern='^\\d+\\.\\d+(\\.\\d+)?$',
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var bills_through_adcp : bool | None
var canonical_catalog_version : str | None
var has_creative_library : bool | None
var localization : Localization | None
var model_config
var multiplicity : Multiplicity | None
var preview : Preview | None
var refinable_retention_seconds : int | None
var representation_resolution : RepresentationResolution | None
var supported_formats : list[SupportedFormat] | None
var supports_compliance : bool | None
var supports_evaluator : bool | None
var supports_generation : bool | None
var supports_refinement : bool | None
var supports_revisions : bool | None
var supports_spend_controls : bool | None
var supports_transformation : bool | None
var supports_transformers : bool | None

Inherited members

class CreativeSpecs (**data: Any)
Expand source code
class CreativeSpecs(AdCPBaseModel):
    vast_versions: Annotated[
        list[VastVersion] | None,
        Field(
            description='Seller-wide VAST execution ceiling. Each product format option declares its binding accepted subset in `params.vast_versions`.',
            min_length=1,
        ),
    ] = None
    macro_resolution_capabilities: Annotated[
        list[MacroResolutionCapability] | None,
        Field(
            description='Seller-wide ceiling for exact macro processing tuples (dialect identity/revision, semantic mapping, operation, actor, context, and encoding). It never proves a product execution path supports the same tuple and does not claim tracker firing; inspect the selected format option and, when standardized, product tracker capabilities.',
            min_length=1,
        ),
    ] = None
    mraid_versions: Annotated[
        list[MraidVersion] | None,
        Field(description='MRAID versions supported for rich media mobile creatives'),
    ] = None
    vpaid: Annotated[
        StrictBool | None, Field(description='VPAID support for interactive video ads')
    ] = None
    simid: Annotated[
        StrictBool | None, Field(description='SIMID support for interactive video ads')
    ] = None
    vast_validation: Annotated[
        VastValidation | None,
        Field(
            description="Level of VAST asset validation the seller performs at sync_creatives (including dry_run): 'structural' checks manifest shape and format requirements only and never inspects the VAST document; 'document' additionally parses the VAST document and can return VAST_PARSE_FAILED / VAST_VERSION_MISMATCH; 'wrapper' additionally resolves the wrapper chain and can return VAST_WRAPPER_DEPTH_EXCEEDED. Absent means 'structural'. See the VAST Validation section of the video channel documentation for the normative checks at each level."
        ),
    ] = VastValidation.structural

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var macro_resolution_capabilities : list[MacroResolutionCapability] | None
var model_config
var mraid_versions : list[MraidVersion] | None
var simid : bool | None
var vast_validation : VastValidation | None
var vast_versions : list[VastVersion] | None
var vpaid : bool | None

Inherited members

class Endpoint (**data: Any)
Expand source code
class Endpoint(AdCPBaseModel):
    transports: Annotated[
        list[Transport3],
        Field(
            description='Available protocol transports. Hosts select based on their capabilities.',
            min_length=1,
        ),
    ]
    preferred: Annotated[
        Type9 | None, Field(description='Preferred transport when host supports multiple')
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var preferred : Type9 | None
var transports : list[Transport3]

Inherited members

class Execution (**data: Any)
Expand source code
class Execution(AdCPBaseModel):
    trusted_match: Annotated[
        TrustedMatch | None,
        Field(
            description='Trusted Match Protocol (TMP) support. Presence of this object indicates the seller has TMP infrastructure deployed. Check individual products via get_products for per-product TMP capabilities.'
        ),
    ] = None
    axe_integrations: Annotated[
        list[AnyUrl] | None,
        Field(
            deprecated=True,
            description='Deprecated. Legacy AXE integrations. Use trusted_match for new integrations.',
        ),
    ] = None
    creative_specs: Annotated[
        CreativeSpecs | None, Field(description='Creative specification support')
    ] = None
    targeting: Annotated[
        Targeting | None,
        Field(
            description='Targeting capabilities. If declared true/supported, buyer can use these targeting parameters and seller MUST honor them.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var axe_integrations : list[pydantic.networks.AnyUrl] | None
var creative_specs : CreativeSpecs | None
var model_config
var targeting : Targeting | None
var trusted_match : TrustedMatch | None

Inherited members

class ExperimentalFeature (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class ExperimentalFeature(ScalarStr):
    __slots__ = ()
    _constraints = {
        'max_length': 128,
        'min_length': 1,
        'pattern': '^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$',
    }
    _json_schema_extra = {
        'description': 'Dot-separated lowercase identifier for an experimental AdCP surface, such as protocol.principal or media_buy.reporting_delivery.',
        'title': 'Experimental Feature ID',
    }

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class SignalsFeatures (**data: Any)
Expand source code
class Features(AdCPBaseModel):
    __pydantic_extra__: Dict[str, StrictBool]
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_signals: Annotated[
        StrictBool | None,
        Field(
            deprecated=True,
            description='DEPRECATED. Legacy wire flag for structured signal_ref references to provider-published signal definitions. New agents SHOULD omit this flag; callers MUST NOT require it before using signal_ref with the Signals protocol.',
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

Raises [ValidationError][pydantic_core.ValidationError] if the input data 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_signals : bool | None
var model_config

Inherited members

class Features (**data: Any)
Expand source code
class Features1(AdCPBaseModel):
    inline_creative_management: Annotated[
        StrictBool | None,
        Field(
            deprecated=True,
            description='Deprecated 3.x compatibility capability for creatives provided inline in create_media_buy and update_media_buy package payloads. buy_products, accept_proposal, and control_media_buy never accept inline creatives. New integrations use the dedicated creative lifecycle. Removed in 4.0.',
        ),
    ] = None
    property_list_filtering: Annotated[
        StrictBool | None,
        Field(
            description='Honors property_list parameter in get_products to filter results to buyer-approved properties'
        ),
    ] = None
    catalog_management: Annotated[
        StrictBool | None,
        Field(
            description='Supports sync_catalogs task for catalog feed management with platform review and approval'
        ),
    ] = None
    catalog_item_availability_updates: Annotated[
        StrictBool | None,
        Field(
            description='Supports buyer-pushed item_availability_updates and item_availability_queries on sync_catalogs for immediate suppression/restoration and current-state readback in buyer-managed catalogs. Seller declarations may be true only with catalog_management: true; buyer required_features filters may request this feature alone. Requests containing availability operations are synchronous and accept at most 1,000 combined update and query entries. A successful suppress covers selection, dynamic rendering, and cached or pre-generated creatives materialized from the item. Internal lineage MUST retain resolved_account_id, catalog_id, catalog_generation, and item_id. Static creatives supplied or promoted by the buyer without catalog lineage remain outside this automatic guarantee. Suppression persists across feed refreshes and ordinary upserts until restore, expires_at, or catalog deletion. A seller that does not declare true MUST reject availability operations with UNSUPPORTED_FEATURE before lookup or mutation and MUST NOT interpret them as discovery. This does not control seller-owned wholesale inventory or let restore bypass seller controls.'
        ),
    ] = None
    committed_metrics_supported: Annotated[
        StrictBool | None,
        Field(
            description="Seller has per-package snapshot infrastructure for the reporting contract. When true, the seller MUST populate `package.committed_metrics` on committed `create_media_buy` responses where `confirmed_at` is non-null, MUST omit `package.committed_metrics` while `confirmed_at` is null for a provisional buy, and MUST honor append-only mid-flight metric additions via `update_media_buy`. The unified `committed_metrics` array (per the metric-accountability design) covers both standard and vendor-defined metric entries, so a single flag is load-bearing. Buyers filtering on this flag are detecting 'this seller can stamp the reporting contract,' which closes the audit gap from PR #3510 where absence of `committed_metrics` was indistinguishable between 'didn't snapshot' and 'snapshot infrastructure not implemented.'"
        ),
    ] = None
    seller_optimized_budget: Annotated[
        StrictBool | None,
        Field(
            description="Supports the core seller-optimized shared-budget contract for budget_allocation.mode `seller_optimized`: one hard shared total_budget, seller allocation of that total across the buy's packages against budget_allocation.optimization_goals, media-buy-level pacing, and echo of the allocation configuration on buy read surfaces. Sellers declaring true MUST accept eligible explicit-package and proposal executions that use only these core controls and MUST enforce the aggregate budget. Core media-buy pacing: sellers declaring true MUST accept omitted media-buy pacing (which defaults to even when total_budget is present) and pacing `even` on seller-optimized buys; they MAY reject `asap` or `front_loaded` with `UNSUPPORTED_FEATURE` (error.field `pacing`) before any provider mutation, and MUST NOT silently coerce them to `even`. Package-level controls inside a seller-optimized buy are separate capabilities: package budget caps (seller_optimized_package_budgets), package minimum-spend targets (seller_optimized_min_spend_targets), and package pacing (seller_optimized_package_pacing). A seller declaring this feature but not one of those sub-capabilities MUST reject any request that would leave that package control on a seller-optimized buy with `UNSUPPORTED_FEATURE` before any over-subscription validation or provider mutation, and MUST NOT silently drop, soften, or coerce it. Over-subscription validation (`INVALID_REQUEST`) applies only to package controls the seller has declared; see seller_optimized_min_spend_targets. Product combinations may still be rejected when their currencies, optimization capabilities, pricing terms, or delivery constraints are incompatible. Sellers that do not declare this feature MUST reject any request carrying `budget_allocation.mode: 'seller_optimized'` with `UNSUPPORTED_FEATURE` before any provider mutation, and MUST NOT coerce the request to fixed allocation."
        ),
    ] = None
    seller_optimized_package_budgets: Annotated[
        StrictBool | None,
        Field(
            description='Honors package `budget` as an optional hard lifetime package spend cap inside a seller-optimized buy: packages[].budget and new_packages[].budget on create_media_buy and update_media_buy, purchases[].budget on buy_products, package budget controls on control_media_buy, and max_spend_percentage on seller-optimized proposal allocations. The cap is a ceiling, not a reserved or current allocation, and package caps may sum above total_budget. Meaningful only with seller_optimized_budget: true; seller declarations may be true only with seller_optimized_budget: true, while buyer required_features filters may request this feature alone. A seller that declares seller_optimized_budget without this feature MUST reject a request that would leave a package budget on a seller-optimized buy, including an allocation-mode switch that retains fixed-mode package budgets (the buyer clears them with null in the same atomic update), with `UNSUPPORTED_FEATURE` before any over-subscription validation or provider mutation, and MUST NOT issue seller-optimized proposals carrying max_spend_percentage. Does not govern fixed allocation, where package budgets remain required.'
        ),
    ] = None
    seller_optimized_min_spend_targets: Annotated[
        StrictBool | None,
        Field(
            description='Honors package `min_spend_target` as a soft lifetime minimum-spend target inside a seller-optimized buy: packages[].min_spend_target and new_packages[].min_spend_target on create_media_buy and update_media_buy, purchases[].min_spend_target on buy_products, package min_spend_target controls on control_media_buy, and min_spend_target_percentage on seller-optimized proposal allocations. The seller SHOULD attempt to deliver at least the target before allocating incremental spend elsewhere; it is not a billing or delivery guarantee. Meaningful only with seller_optimized_budget: true; seller declarations may be true only with seller_optimized_budget: true, while buyer required_features filters may request this feature alone. Sellers declaring this feature MUST reject package minimum-spend targets summing above total_budget with `INVALID_REQUEST` before mutation, and, when they also declare seller_optimized_package_budgets, MUST likewise reject a min_spend_target above its own package budget. A seller that declares seller_optimized_budget without this feature MUST reject a request carrying a numeric min_spend_target with `UNSUPPORTED_FEATURE` before any over-subscription validation or provider mutation, so an over-subscribed target sent to such a seller yields `UNSUPPORTED_FEATURE`, and MUST NOT issue seller-optimized proposals carrying min_spend_target_percentage.'
        ),
    ] = None
    seller_optimized_package_pacing: Annotated[
        StrictBool | None,
        Field(
            description='Honors package `pacing` as subordinate per-package pacing inside a seller-optimized buy, in addition to the media-buy-level pacing covered by seller_optimized_budget: packages[].pacing and new_packages[].pacing on create_media_buy and update_media_buy, purchases[].pacing on buy_products, package pacing controls on control_media_buy, and allocation pacing on seller-optimized proposals. Package pacing MUST NOT cause delivery to exceed aggregate media-buy pacing. Meaningful only with seller_optimized_budget: true; seller declarations may be true only with seller_optimized_budget: true, while buyer required_features filters may request this feature alone. Package pacing equal to the effective media-buy pacing adds no subordinate constraint and does not require this feature; buyers SHOULD omit package pacing on seller-optimized buys unless this feature is advertised. A seller that declares seller_optimized_budget without this feature MUST reject a request that would leave package pacing differing from media-buy pacing on a seller-optimized buy, including an allocation-mode switch that retains such fixed-mode package pacing (the buyer can align it in the same update), with `UNSUPPORTED_FEATURE` before any provider mutation, and MUST NOT issue seller-optimized proposals carrying allocation pacing. Does not govern package pacing in fixed allocation.'
        ),
    ] = None
    bidding_policy: Annotated[
        BiddingPolicyCapability | None,
        Field(
            description='Structured support for canonical bidding by authored scope, allocation context, mode, strength, and strength-qualified multi-field combination. Presence does not imply support for both scopes, both allocation modes, or every policy shape. Sellers MUST preserve every advertised semantic exactly and reject unadvertised policies rather than translating them.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var bidding_policy : BiddingPolicyCapability | None
var canonical_creatives : bool | None
var catalog_item_availability_updates : bool | None
var catalog_management : bool | None
var committed_metrics_supported : bool | None
var model_config
var property_list_filtering : bool | None
var seller_optimized_budget : bool | None
var seller_optimized_min_spend_targets : bool | None
var seller_optimized_package_budgets : bool | None
var seller_optimized_package_pacing : bool | None

Instance variables

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

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

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

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

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

Inherited members

class GeoMetros (**data: Any)
Expand source code
class GeoMetros(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    nielsen_dma: StrictBool | None = None
    uk_itl1: StrictBool | None = None
    uk_itl2: StrictBool | None = None
    eurostat_nuts2: StrictBool | None = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var eurostat_nuts2 : bool | None
var model_config
var nielsen_dma : bool | None
var uk_itl1 : bool | None
var uk_itl2 : bool | None

Inherited members

class GeoPostalAreas (**data: Any)
Expand source code
class GeoPostalAreas(AdCPBaseModel):
    __pydantic_extra__: Dict[
        str, list[GeoPostalAreasAdditionalPropertyEnum]
    ]
    model_config = ConfigDict(
        extra='allow',
    )
    US: Annotated[list[ME] | None, Field(min_length=1)] = None
    GB: Annotated[list[GBEnum] | None, Field(min_length=1)] = None
    CA: Annotated[list[CAEnum] | None, Field(min_length=1)] = None
    DE: Annotated[list[Literal['plz']] | None, Field(min_length=1)] = None
    CH: Annotated[list[Literal['plz']] | None, Field(min_length=1)] = None
    AT: Annotated[list[Literal['plz']] | None, Field(min_length=1)] = None
    FR: Annotated[list[Literal['code_postal']] | None, Field(min_length=1)] = None
    AU: Annotated[list[Literal['postcode']] | None, Field(min_length=1)] = None
    BR: Annotated[list[Literal['cep']] | None, Field(min_length=1)] = None
    IN: Annotated[list[Literal['pin']] | None, Field(min_length=1)] = None
    ZA: Annotated[list[Literal['postal_code']] | None, Field(min_length=1)] = None
    us_zip: Annotated[StrictBool | None, Field(deprecated=True)] = None
    us_zip_plus_four: Annotated[StrictBool | None, Field(deprecated=True)] = None
    gb_outward: Annotated[StrictBool | None, Field(deprecated=True)] = None
    gb_full: Annotated[StrictBool | None, Field(deprecated=True)] = None
    ca_fsa: Annotated[StrictBool | None, Field(deprecated=True)] = None
    ca_full: Annotated[StrictBool | None, Field(deprecated=True)] = None
    de_plz: Annotated[StrictBool | None, Field(deprecated=True)] = None
    fr_code_postal: Annotated[StrictBool | None, Field(deprecated=True)] = None
    au_postcode: Annotated[StrictBool | None, Field(deprecated=True)] = None
    ch_plz: Annotated[StrictBool | None, Field(deprecated=True)] = None
    at_plz: Annotated[StrictBool | None, Field(deprecated=True)] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var AT : list[typing.Literal['plz']] | None
var AU : list[typing.Literal['postcode']] | None
var BR : list[typing.Literal['cep']] | None
var CA : list[CAEnum] | None
var CH : list[typing.Literal['plz']] | None
var DE : list[typing.Literal['plz']] | None
var FR : list[typing.Literal['code_postal']] | None
var GB : list[GBEnum] | None
var IN : list[typing.Literal['pin']] | None
var US : list[ME] | None
var ZA : list[typing.Literal['postal_code']] | None
var at_plz : bool | None
var au_postcode : bool | None
var ca_fsa : bool | None
var ca_full : bool | None
var ch_plz : bool | None
var de_plz : bool | None
var fr_code_postal : bool | None
var gb_full : bool | None
var gb_outward : bool | None
var model_config
var us_zip : bool | None
var us_zip_plus_four : bool | None

Inherited members

class GeoProximity (**data: Any)
Expand source code
class GeoProximity(AdCPBaseModel):
    radius: Annotated[
        StrictBool | None,
        Field(
            description='Whether seller supports simple radius targeting (distance circle from a point)'
        ),
    ] = None
    travel_time: Annotated[
        StrictBool | None,
        Field(
            description='Whether seller supports travel time isochrone targeting (requires a routing engine)'
        ),
    ] = None
    geometry: Annotated[
        StrictBool | None,
        Field(
            description='Whether seller supports pre-computed GeoJSON geometry (buyer provides the polygon)'
        ),
    ] = None
    transport_modes: Annotated[
        list[TransportMode] | None,
        Field(
            description='Transport modes supported for travel_time isochrones. Only relevant when travel_time is true.',
            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 geometry : bool | None
var model_config
var radius : bool | None
var transport_modes : list[TransportMode] | None
var travel_time : bool | None

Inherited members

class Governance (**data: Any)
Expand source code
class Governance(AdCPBaseModel):
    runtime_attestations: Annotated[
        RuntimeAttestations | None,
        Field(
            description='Signal-activation policy for the portable attestation support declared in adcp.attestations. Presence means check_governance accepts runtime_attestations[] for purchase_type signal_activation. The claim_types list MUST be a subset of adcp.attestations.accepted_claim_types; issuer, resolver, verifier, proof-format, and delivery allowlists remain authoritative in the shared adcp.attestations block rather than being duplicated here.'
        ),
    ] = None
    aggregation_window_days: Annotated[
        SchemaInt | None,
        Field(
            description='Trailing window (in days) over which this governance agent aggregates committed spend when evaluating dollar-valued thresholds (reallocation_threshold, human_review triggers, registry-policy floors). Required for fragmentation defense: without aggregation, a buyer can split a single large spend into many sub-threshold commits across plans / task surfaces / time and bypass every dollar-gated escalation. Aggregation is keyed on (buyer_agent, seller_agent, account_id) and spans all spend-commit task types. Upper bound 365 represents a one-year trailing window (fiscal-year alignment with grace); governance agents needing longer scopes negotiate via operator sign-off, not this capability. No schema default: absence of this field indicates the governance agent has not committed to any aggregation window and buyers MUST assume per-commit evaluation only (the fragmentation attack surface is open). A declared value of 30 is a common starting point but is not implied by omission. Buyers depending on a specific window for compliance MUST check this capability before relying on aggregation semantics — an agent declaring 7 days does not defend against fragmentation spread across a 30-day quarter-end push.',
            ge=1,
            le=365,
        ),
    ] = None
    property_features: Annotated[
        list[PropertyFeature] | None,
        Field(
            description='Property features this governance agent can evaluate. Each feature describes a score, rating, or certification the agent can provide for properties.'
        ),
    ] = None
    creative_features: Annotated[
        list[CreativeFeature] | None,
        Field(
            description='Creative features this governance agent can evaluate. Each feature describes a score, rating, or assessment the agent can provide for creatives (e.g., security scanning, creative quality, content categorization).'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var aggregation_window_days : int | None
var creative_features : list[CreativeFeature] | None
var model_config
var property_features : list[PropertyFeature] | None
var runtime_attestations : RuntimeAttestations | None

Inherited members

class Idempotency (**data: Any)
Expand source code
class Idempotency(AdCPBaseModel):
    supported: Annotated[
        Literal[True],
        Field(
            description='Discriminator. True means the seller deduplicates replays — a repeat of the same idempotency_key within replay_ttl_seconds returns the cached response without re-executing side effects.'
        ),
    ]
    replay_ttl_seconds: Annotated[
        SchemaInt,
        Field(
            description="How long the seller retains a canonical response or committed-outcome tombstone for an idempotency_key, measured from the successful mutation's durable commit time. The completed key record and canonical request hash MUST remain available until at least committed_at + this interval, independently of the lifecycle of any resource the request created; a UNIQUE idempotency_key column on the resource row alone does not satisfy this contract. Within this window, a replay with the same key + equivalent canonical payload returns the cached response, or COMMITTED_RESOURCE_PURGED when the mutation committed but the affected resource was independently deleted or purged before the canonical success response could be durably recorded; a replay with a different canonical payload returns IDEMPOTENCY_CONFLICT. An unresolved in-flight or reconciliation-required claim is retained regardless of this completed-entry clock. A replay past a completed entry's window returns IDEMPOTENCY_EXPIRED when the seller can still distinguish 'seen and evicted' from 'never seen'. Minimum 3600 (1h); recommended 86400 (24h). Maximum 604800 (7 days) — longer windows force buyers to retain secret keys at rest for extended periods and grow the seller's cache table without bounded benefit.",
            ge=3600,
            le=604800,
        ),
    ]
    in_flight_max_seconds: Annotated[
        SchemaInt | None,
        Field(
            description="Maximum active execution lease in seconds before the seller stops or replaces the original handler and transitions the durable idempotency claim to reconciliation-required per L1/security.mdx rule 9. Expiry does not release or evict an unresolved claim and never permits reinvocation while commit state is ambiguous. Buyer SDKs use this value to cap an individual retry wait when they see `IDEMPOTENCY_IN_FLIGHT`, rather than using the much wider `replay_ttl_seconds` ceiling; it is not a deadline after which they may mint a fresh key. Optional in 3.1 (additive declaration); SDKs that don't see the field fall back to rule 9's order-of-magnitude SHOULD heuristic. Required when `supported: true` in 4.0. MUST be no greater than `replay_ttl_seconds`; validators MUST enforce this cross-field constraint at the test layer since JSON Schema cannot express field-relative bounds. A buyer that observes top-level `error.retry_after` exceeding this value MAY treat that as a seller bug for an actively executing attempt.",
            ge=1,
            le=604800,
        ),
    ] = None
    account_id_is_opaque: Annotated[
        StrictBool | None,
        Field(
            description="When true, the seller derives `account_id` via an HKDF-based one-way transform of the buyer's natural account key rather than echoing the natural key on the wire. Buyers MUST NOT attempt to invert the opaque id and MUST treat it as a blind handle scoped to this seller. Absent or false, callers should assume `account_id` is the natural key (or a server-assigned but non-opaque id). This flag does not change the wire shape, but it DOES change buyer behavior — buyers MUST NOT cache, log, or treat `account_id` as a natural-key analog when this flag is true. Migration note for sellers already returning an opaque id without this flag: set it to true at the next capabilities refresh so buyers stop inferring natural-key semantics; until set, new-buyer replay/retry logic will misclassify these ids as natural keys."
        ),
    ] = False

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var account_id_is_opaque : bool | None
var in_flight_max_seconds : int | None
var model_config
var replay_ttl_seconds : int
var supported : Literal[True]
class IdempotencySupported (**data: Any)
Expand source code
class Idempotency(AdCPBaseModel):
    supported: Annotated[
        Literal[True],
        Field(
            description='Discriminator. True means the seller deduplicates replays — a repeat of the same idempotency_key within replay_ttl_seconds returns the cached response without re-executing side effects.'
        ),
    ]
    replay_ttl_seconds: Annotated[
        SchemaInt,
        Field(
            description="How long the seller retains a canonical response or committed-outcome tombstone for an idempotency_key, measured from the successful mutation's durable commit time. The completed key record and canonical request hash MUST remain available until at least committed_at + this interval, independently of the lifecycle of any resource the request created; a UNIQUE idempotency_key column on the resource row alone does not satisfy this contract. Within this window, a replay with the same key + equivalent canonical payload returns the cached response, or COMMITTED_RESOURCE_PURGED when the mutation committed but the affected resource was independently deleted or purged before the canonical success response could be durably recorded; a replay with a different canonical payload returns IDEMPOTENCY_CONFLICT. An unresolved in-flight or reconciliation-required claim is retained regardless of this completed-entry clock. A replay past a completed entry's window returns IDEMPOTENCY_EXPIRED when the seller can still distinguish 'seen and evicted' from 'never seen'. Minimum 3600 (1h); recommended 86400 (24h). Maximum 604800 (7 days) — longer windows force buyers to retain secret keys at rest for extended periods and grow the seller's cache table without bounded benefit.",
            ge=3600,
            le=604800,
        ),
    ]
    in_flight_max_seconds: Annotated[
        SchemaInt | None,
        Field(
            description="Maximum active execution lease in seconds before the seller stops or replaces the original handler and transitions the durable idempotency claim to reconciliation-required per L1/security.mdx rule 9. Expiry does not release or evict an unresolved claim and never permits reinvocation while commit state is ambiguous. Buyer SDKs use this value to cap an individual retry wait when they see `IDEMPOTENCY_IN_FLIGHT`, rather than using the much wider `replay_ttl_seconds` ceiling; it is not a deadline after which they may mint a fresh key. Optional in 3.1 (additive declaration); SDKs that don't see the field fall back to rule 9's order-of-magnitude SHOULD heuristic. Required when `supported: true` in 4.0. MUST be no greater than `replay_ttl_seconds`; validators MUST enforce this cross-field constraint at the test layer since JSON Schema cannot express field-relative bounds. A buyer that observes top-level `error.retry_after` exceeding this value MAY treat that as a seller bug for an actively executing attempt.",
            ge=1,
            le=604800,
        ),
    ] = None
    account_id_is_opaque: Annotated[
        StrictBool | None,
        Field(
            description="When true, the seller derives `account_id` via an HKDF-based one-way transform of the buyer's natural account key rather than echoing the natural key on the wire. Buyers MUST NOT attempt to invert the opaque id and MUST treat it as a blind handle scoped to this seller. Absent or false, callers should assume `account_id` is the natural key (or a server-assigned but non-opaque id). This flag does not change the wire shape, but it DOES change buyer behavior — buyers MUST NOT cache, log, or treat `account_id` as a natural-key analog when this flag is true. Migration note for sellers already returning an opaque id without this flag: set it to true at the next capabilities refresh so buyers stop inferring natural-key semantics; until set, new-buyer replay/retry logic will misclassify these ids as natural keys."
        ),
    ] = False

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var account_id_is_opaque : bool | None
var in_flight_max_seconds : int | None
var model_config
var replay_ttl_seconds : int
var supported : Literal[True]

Inherited members

class IdempotencyUnsupported (**data: Any)
Expand source code
class Idempotency3(AdCPBaseModel):
    supported: Annotated[
        Literal[False],
        Field(description='Discriminator. False means the seller does not deduplicate retries.'),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var supported : Literal[False]

Inherited members

class Identity (**data: Any)
Expand source code
class Identity(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    brand_json_url: Annotated[
        AnyUrl | None,
        Field(
            description="HTTPS URL of the operator's brand.json (typically `https://{operator-domain}/.well-known/brand.json`). Trust-root pointer for this agent's signing keys. See [security.mdx §Discovering an agent's signing keys via `brand_json_url`](https://adcontextprotocol.org/docs/building/by-layer/L1/security#discovering-an-agents-signing-keys-via-brand_json_url) for the verifier algorithm and `x-adcp-validation` for structured constraints. Distinct from `sponsored_intelligence.brand_url`, which is a rendering pointer for SI agent visuals — verifiers MUST use this field for key discovery and MUST NOT fall back to `sponsored_intelligence.brand_url` as a trust-root pointer."
        ),
    ] = None
    per_principal_key_isolation: Annotated[
        StrictBool | None,
        Field(
            description="When true, this multi-principal operator scopes signing keys per-principal so a single principal's key compromise does not silently re-scope across principals served by the same operator. `kid` values remain opaque to verifiers per RFC 7517; any operator-side naming convention (e.g., `{operator}:{principal}:{key_version}`) is internal bookkeeping and MUST NOT be parsed by verifiers. See docs/building/understanding/security-model.mdx."
        ),
    ] = False
    key_origins: Annotated[
        KeyOrigins | None,
        Field(
            description='Map of signing-key surface/purpose → publishing origin, so counterparties can verify origin separation (e.g., governance keys served from a separate origin than transport/webhook keys) at onboarding. Absent means the operator has not declared a separation scheme; receivers SHOULD assume shared-origin. Every entry listed MUST have a corresponding signing posture declared elsewhere — `request_signing` requires non-empty `request_signing.supported_for`/`required_for`/`protocol_methods_supported_for`/`protocol_methods_required_for`; `webhook_signing` requires `webhook_signing.supported === true` and names the webhook delivery surface, not a required live `adcp_use: "webhook-signing"` key purpose — otherwise the consistency check at signature-verification time has nothing to anchor against. See `x-adcp-validation` and docs/building/implementation/security.mdx §Origin separation.'
        ),
    ] = None
    compromise_notification: Annotated[
        CompromiseNotification | None,
        Field(
            description='Whether this agent emits the `identity.compromise_notification` webhook event on key revocation due to known or suspected compromise (as opposed to scheduled rotation). Subscribers use this to bound the window between compromise detected and verifiers converging on revocation. See docs/building/implementation/webhooks.mdx §identity.compromise_notification.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var brand_json_url : pydantic.networks.AnyUrl | None
var compromise_notification : CompromiseNotification | None
var key_origins : KeyOrigins | None
var model_config
var per_principal_key_isolation : bool | None

Inherited members

class KeyOrigins (**data: Any)
Expand source code
class KeyOrigins(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    governance_signing: Annotated[
        AnyUrl | None,
        Field(description='Origin (scheme + host) serving the governance-signing JWKS.'),
    ] = None
    request_signing: Annotated[
        AnyUrl | None, Field(description='Origin (scheme + host) serving the request-signing JWKS.')
    ] = None
    webhook_signing: Annotated[
        AnyUrl | None,
        Field(
            description='Origin (scheme + host) serving the JWKS used for webhook delivery. Webhooks are signed with `adcp_use: "request-signing"` keys; the deprecated `adcp_use: "webhook-signing"` value remains accepted during the backward-compatibility window.'
        ),
    ] = None
    tmp_signing: Annotated[
        AnyUrl | None,
        Field(
            description='Origin (scheme + host) serving the TMP-signing JWKS, when this operator participates in TMP.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var governance_signing : pydantic.networks.AnyUrl | None
var model_config
var request_signing : pydantic.networks.AnyUrl | None
var tmp_signing : pydantic.networks.AnyUrl | None
var webhook_signing : pydantic.networks.AnyUrl | None

Inherited members

class KeywordTargets (**data: Any)
Expand source code
class KeywordTargets(AdCPBaseModel):
    supported_match_types: Annotated[
        list[MatchType],
        Field(
            description='Match types this seller supports for keyword targets. Sellers must reject goals with unsupported match types.',
            min_length=1,
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var supported_match_types : list[MatchType]

Inherited members

class LifecycleTool (*args, **kwds)
Expand source code
class LifecycleTool(StrEnum):
    list_products = 'list_products'
    request_proposals = 'request_proposals'
    refine_proposals = 'refine_proposals'
    decline_proposals = 'decline_proposals'
    buy_products = 'buy_products'
    accept_proposal = 'accept_proposal'
    control_media_buy = 'control_media_buy'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var accept_proposal
var buy_products
var control_media_buy
var decline_proposals
var list_products
var refine_proposals
var request_proposals
class MatchingLatencyHours (**data: Any)
Expand source code
class MatchingLatencyHours(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    min: Annotated[SchemaInt | None, Field(ge=0)] = None
    max: Annotated[SchemaInt | None, Field(ge=0)] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var max : int | None
var min : int | None
var model_config

Inherited members

class Measurement (**data: Any)
Expand source code
class Measurement(AdCPBaseModel):
    produces_performance_feedback: Annotated[
        StrictBool | None,
        Field(
            description="Whether this measurement agent produces compact provide_performance_feedback assertions for a buyer-controlled orchestrator gateway. In the first experimental tier the provider reads delivery through the gateway's get_media_buy_delivery task and returns assertions through its provide_performance_feedback task. The gateway decides what to forward to each seller."
        ),
    ] = False
    metrics: Annotated[
        list[Metric],
        Field(
            description="Metrics this agent computes. Each entry is identified by `metric_id` within the vendor's vocabulary; the canonical reference everywhere a measurement value appears (`committed_metrics`, `vendor_metric_values`, `missing_metrics`) is the tuple `(vendor.domain, vendor.brand_id, metric_id)`.",
            min_length=1,
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var metrics : list[Metric]
var model_config
var produces_performance_feedback : bool | None

Inherited members

class MediaBuy (**data: Any)
Expand source code
class MediaBuy(_MediaBuy):
    """Media-buy capabilities using the canonical reporting model identity."""

    reporting_delivery: ReportingDeliveryCapabilities | None = None  # type: ignore[assignment]

Media-buy capabilities using the canonical reporting model identity.

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

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

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

Ancestors

Class variables

var model_config
var reporting_delivery : ReportingDeliveryCapabilities | None

Inherited members

class Metric (**data: Any)
Expand source code
class Metric(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    metric_id: Annotated[
        str,
        Field(
            description="Identifier for the metric within the vendor's vocabulary. Combined with the agent's BrandRef, forms the canonical tuple `(vendor.domain, vendor.brand_id, metric_id)`. Each metric_id MUST be unique within a single agent's catalog.",
            examples=[
                'attention_units',
                'gco2e_per_impression',
                'demographic_reach',
                'co_view_index',
                'incremental_lift_percent',
            ],
            max_length=64,
            min_length=1,
            pattern='^[a-z][a-z0-9_]*$',
            title='Vendor Metric ID',
        ),
    ]
    standard_reference: Annotated[
        AnyUrl | None,
        Field(
            description='Optional URI pointing at the published standard this metric IMPLEMENTS (e.g., IAB Attention Measurement Guidelines, MRC Viewable Impression Measurement, GARM emissions framework). Distinct from `accreditations[]` — `standard_reference` is what the metric is built against; `accreditations[]` is third-party certification that the implementation actually conforms. Buyer agents normalizing across vendors SHOULD apply the AdCP URL canonicalization rules before comparing — vendors implementing the same standard MAY use different URL forms for the same canonical document.'
        ),
    ] = None
    accreditations: Annotated[
        list[Accreditation] | None,
        Field(
            description="Third-party accreditations this metric holds (MRC, ARF, JIC, ABC, BARB, AGOF, etc.). Distinct from `standard_reference`: a metric can implement a standard without being independently accredited. Buyers asking 'is this MRC-accredited?' SHOULD check this array, not just `standard_reference`. Each entry names the accrediting body and optionally pins a certification ID, validity date, and evidence URL."
        ),
    ] = None
    unit: Annotated[
        str | None,
        Field(
            description='Unit of the metric value when reported via `vendor_metric_values.value` (e.g., `score`, `seconds`, `persons`, `gCO2e`, `lift_percent`, `USD`). Buyers SHOULD render the unit alongside the value rather than computing units locally; sellers populating `vendor_metric_values.unit` MUST match this declaration when present.',
            examples=['score', 'seconds', 'persons', 'gCO2e', 'lift_percent', 'index', 'USD'],
        ),
    ] = None
    description: Annotated[
        str | None,
        Field(
            description='Human-readable description of what this metric measures and any relevant methodology notes. Surfaced in buyer-agent UX when explaining the metric to humans.'
        ),
    ] = None
    methodology_url: Annotated[
        AnyUrl | None,
        Field(
            description="URL to the vendor's full methodology documentation for this metric. Buyers SHOULD link or fetch this when human review of the methodology is in scope (compliance, RFP review, accreditation audit). Field name mirrors `governance.property_features[].methodology_url`."
        ),
    ] = None
    methodology_version: Annotated[
        str | None,
        Field(
            description='Optional version identifier (semver, ISO date, or vendor-defined version string) for the methodology this metric currently implements. When present, buyer agents pin the contracted version via `committed_metrics[].methodology_version` (vendor scope) so silent vendor methodology changes are detectable; absence means the vendor does not version their methodology and buyers MUST treat any change as untracked.',
            examples=['v2.1', '2026-Q1', '1.0'],
        ),
    ] = None
    ext: Annotated[
        dict[str, Any] | None,
        Field(
            description='Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.',
            title='Extension Object',
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var accreditations : list[Accreditation] | None
var description : str | None
var ext : dict[str, typing.Any] | None
var methodology_url : pydantic.networks.AnyUrl | None
var methodology_version : str | None
var metric_id : str
var model_config
var standard_reference : pydantic.networks.AnyUrl | None
var unit : str | None

Inherited members

class Modalities (**data: Any)
Expand source code
class Modalities(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    conversational: Annotated[
        StrictBool | None, Field(description='Pure text exchange - the baseline modality')
    ] = True
    voice: Annotated[
        StrictBool | Voice | None, Field(description='Audio-based interaction using brand voice')
    ] = None
    video: Annotated[
        StrictBool | Video | None, Field(description='Brand video content playback')
    ] = None
    avatar: Annotated[
        StrictBool | Avatar | None, Field(description='Animated video presence with brand avatar')
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var avatar : bool | Avatar | None
var conversational : bool | None
var model_config
var video : bool | Video | None
var voice : bool | Voice | None

Inherited members

class NegativeKeywords (**data: Any)
Expand source code
class NegativeKeywords(AdCPBaseModel):
    supported_match_types: Annotated[
        list[MatchType],
        Field(
            description='Match types this seller supports for negative keywords. Sellers must reject goals with unsupported match types.',
            min_length=1,
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var supported_match_types : list[MatchType]

Inherited members

class Portfolio (**data: Any)
Expand source code
class Portfolio(AdCPBaseModel):
    publisher_domains: Annotated[
        list[PublisherDomain],
        Field(
            description="Publisher domains this seller is authorized to represent. Buyers should fetch each publisher's adagents.json for property definitions.",
            min_length=1,
        ),
    ]
    primary_channels: Annotated[
        list[MediaChannel] | None,
        Field(
            description="Complete list of AdCP media channels for which this sales agent accepts and can meaningfully answer product-discovery briefs. When present, this is an exhaustive brief-routing allowlist: buyers MAY skip the agent when a brief's requested channels do not intersect it. Omission means channel scope is unknown and MUST NOT be interpreted as support for every channel. This is a routing pre-filter, not a promise of current product availability."
        ),
    ] = None
    primary_countries: Annotated[
        list[PrimaryCountry] | None,
        Field(
            description="Complete list of ISO 3166-1 alpha-2 countries for which this sales agent accepts and can meaningfully answer product-discovery briefs. When present, this is an exhaustive brief-routing allowlist: buyers MAY skip the agent when a brief's requested countries do not intersect it. Omission means country scope is unknown and MUST NOT be interpreted as global coverage. This is a routing pre-filter, not a promise of current product availability and not an executable geo-targeting declaration; media_buy.execution.targeting geo capabilities and each product's overlay_support remain authoritative for targeting execution."
        ),
    ] = None
    description: Annotated[
        str | None,
        Field(
            description='Markdown-formatted description of the inventory portfolio', max_length=5000
        ),
    ] = None
    advertising_policies: Annotated[
        str | None,
        Field(
            description='Advertising content policies, restrictions, and guidelines',
            max_length=10000,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var advertising_policies : str | None
var description : str | None
var model_config
var primary_channels : list[MediaChannel] | None
var primary_countries : list[PrimaryCountry] | None
var publisher_domains : list[PublisherDomain]

Inherited members

class Preview (**data: Any)
Expand source code
class Preview(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    routes: Annotated[
        list[Route],
        Field(
            description='Agent-local preview routes and their implementation origin. Authority is resolved from publisher placement delegation, never from this self-description.',
            min_length=1,
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var routes : list[Route]

Inherited members

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

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var agent_approximation
var platform_native
class RequestSigning (**data: Any)
Expand source code
class RequestSigning(AdCPBaseModel):
    supported: Annotated[
        StrictBool,
        Field(
            description='Whether this agent verifies RFC 9421 signatures on incoming requests. When true, signatures present on requests are validated per the AdCP request-signing profile. When false or absent, signatures are ignored (requests are bearer-authenticated only).'
        ),
    ]
    covers_content_digest: Annotated[
        CoversContentDigest | None,
        Field(
            description="Policy for content-digest coverage in request signatures. In AdCP 3.2 and later, an agent with request_signing.supported=true MUST explicitly emit 'required': every accepted signature on a request with a body covers content-digest, and a body-unbound signature is rejected with request_signature_components_incomplete. Omission retains the legacy effective default of 'either' only for a 3.0/3.1 response; 3.2 responses require this field explicitly. 'either' and 'forbidden' are deprecated legacy 3.0/3.1 postures retained only for version negotiation with pre-3.2 peers; they MUST NOT be advertised as a 3.2 signing posture and are removed in 4.0. A shared endpoint MUST select the verifier policy from trusted endpoint configuration and negotiated capabilities before dispatch, never from an unbound request-body version field."
        ),
    ] = None
    required_for: Annotated[
        list[Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]] | None,
        Field(
            description="AdCP protocol operation names (e.g., 'create_media_buy') for which this agent rejects an unsigned request with request_signature_required unless an independently valid configured fallback authenticator succeeds. Not MCP tool names, A2A skill names, or any transport-specific rename — verifiers MUST NOT accept operation names that are not defined by the AdCP protocol spec. JSON-RPC protocol method names like `tasks/cancel` belong in `protocol_methods_required_for`, not here. Empty in 3.0 by default; sellers populate selectively during per-counterparty pilots. In 4.0 this list MUST include all spend-committing operations the agent supports (create_media_buy, acquire_*, etc.). Every operation listed MUST also appear in `supported_for`; see `x-adcp-validation`.",
            validate_default=True,
        ),
    ] = []
    warn_for: Annotated[
        list[Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]] | None,
        Field(
            description='AdCP protocol operation names for shadow-mode verification. The verifier records missing signatures and well-formed signatures that fail verification or body binding, but MUST NOT establish verified-signer identity from a failed signature; processing continues only when an independent bearer, API-key, or mTLS authenticator succeeds. A partial or malformed Signature / Signature-Input pair always hard-rejects. Used as a bridge between supported_for and required_for. Precedence: required_for > warn_for > supported_for. An operation MUST NOT appear in both warn_for and required_for; see x-adcp-validation.',
            validate_default=True,
        ),
    ] = []
    supported_for: Annotated[
        list[Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]] | None,
        Field(
            description='AdCP protocol operation names for which this agent verifies signatures when present but does not require them. Under the 3.2 profile, a presented signature on a body-bearing request without content-digest coverage rejects even though an unsigned request may use configured fallback authentication. Typically a superset of required_for and warn_for.'
        ),
    ] = None
    protocol_methods_supported_for: Annotated[
        list[ProtocolMethodsSupportedForItem] | None,
        Field(
            description="JSON-RPC protocol method names for which this agent verifies signatures when present. Values MUST use exact, case-sensitive equality after JSON decoding: slash-path names such as 'tasks/cancel' and 'tasks/pushNotificationConfig/set' for A2A 0.3, or PascalCase names such as 'CancelTask' and 'CreateTaskPushNotificationConfig' for A2A 1.0. A dual-stack agent lists each supported wire name independently; implementations MUST NOT translate or normalize between protocol versions. The reserved MCP envelope method 'tools/call' is forbidden because its AdCP operation identity is params.name and belongs in supported_for. Under the 3.2 profile, a presented signature on a body-bearing request without content-digest coverage rejects. Disjoint from supported_for, which carries lower_snake_case AdCP operation names only.",
            validate_default=True,
        ),
    ] = []
    protocol_methods_warn_for: Annotated[
        list[ProtocolMethodsWarnForItem] | None,
        Field(
            description='Exact JSON-RPC protocol method names for shadow-mode verification, mirroring warn_for in the AdCP-operation namespace. Wire-name grammar and exact, case-sensitive matching semantics are identical to protocol_methods_supported_for. Missing signatures and well-formed signatures that fail verification or body binding are recorded but MUST NOT establish verified-signer identity; processing continues only when an independent authenticator succeeds. A partial or malformed Signature / Signature-Input pair always hard-rejects. An item MUST NOT appear in both protocol_methods_warn_for and protocol_methods_required_for; see x-adcp-validation.',
            validate_default=True,
        ),
    ] = []
    protocol_methods_required_for: Annotated[
        list[ProtocolMethodsRequiredForItem] | None,
        Field(
            description='Exact JSON-RPC protocol method names for which this agent rejects an unsigned request with request_signature_required unless an independently valid configured fallback authenticator succeeds. Wire-name grammar and exact, case-sensitive matching semantics are identical to protocol_methods_supported_for. Separate namespace from required_for: this bucket binds against the JSON-RPC method field, not tools/call params.name. Every listed method MUST also appear in protocol_methods_supported_for; see x-adcp-validation.',
            validate_default=True,
        ),
    ] = []

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var covers_content_digest : CoversContentDigest | None
var model_config
var protocol_methods_required_for : list[ProtocolMethodsRequiredForItem] | None
var protocol_methods_supported_for : list[ProtocolMethodsSupportedForItem] | None
var protocol_methods_warn_for : list[ProtocolMethodsWarnForItem] | None
var required_for : list[str] | None
var supported : bool
var supported_for : list[str] | None
var warn_for : list[str] | None

Inherited members

class PreviewRoute (**data: Any)
Expand source code
class Route(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    capability_id: Annotated[
        str,
        Field(
            description='Agent-local creative.supported_formats[].capability_id accepted by preview_creative.',
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]
    rendering_origin: Annotated[
        RenderingOrigin,
        Field(
            description="Informational implementation origin. platform_native means the route uses the serving platform's preview machinery; agent_approximation means the agent renders an approximation. Neither value grants authority without a publisher preview_provider delegation."
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var capability_id : str
var model_config
var rendering_origin : RenderingOrigin

Inherited members

class Signals (**data: Any)
Expand source code
class Signals(AdCPBaseModel):
    anonymous_discovery: Annotated[
        StrictBool | None,
        Field(
            description='Whether this agent accepts get_signals discovery without caller credentials in brief or wholesale mode. true means an anonymous discovery request can produce a successful response, but the response may be a public subset and may differ from results for an authenticated principal or selected account. false means get_signals requires an authenticated principal. Absence means unspecified legacy behavior, so callers probe and handle AUTH_MISSING. A valid authenticated request is never rejected merely because credentials were supplied.'
        ),
    ] = None
    data_provider_domains: Annotated[
        list[DataProviderDomain] | None,
        Field(
            description="Data provider domains this signals agent is authorized to resell. Buyers should fetch each data provider's adagents.json for published signal definitions and to verify authorization.",
            min_length=1,
        ),
    ] = None
    discovery_modes: Annotated[
        list[DiscoveryMode] | None,
        Field(
            description="Discovery modes this signals agent supports on get_signals. 'brief' (default — every signals agent supports this): semantic discovery driven by signal_spec or signal_refs, with deprecated signal_ids accepted for older clients. 'wholesale': raw wholesale signals feed enumeration — caller omits signal_spec, signal_refs, and signal_ids and the agent returns its full priced signals feed, paginated, scoped by filters/account/destinations/countries. Agents that do not declare 'wholesale' MAY return INVALID_REQUEST for wholesale calls. Absent declaration is treated as ['brief'].",
            min_length=1,
        ),
    ] = [DiscoveryMode.brief]
    features: Annotated[
        Features | None, Field(description='Optional signals features supported')
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var anonymous_discovery : bool | None
var data_provider_domains : list[DataProviderDomain] | None
var discovery_modes : list[DiscoveryMode] | None
var features : Features | None
var model_config

Inherited members

class Specialism (*args, **kwds)
Expand source code
class Specialism(StrEnum):
    audience_sync = 'audience-sync'
    brand_rights = 'brand-rights'
    buyer_activation = 'buyer-activation'
    buyer_discovery = 'buyer-discovery'
    buyer_monitoring = 'buyer-monitoring'
    buyer_negotiation = 'buyer-negotiation'
    buyer_recovery = 'buyer-recovery'
    collection_lists = 'collection-lists'
    content_standards = 'content-standards'
    creative_ad_server = 'creative-ad-server'
    creative_generative = 'creative-generative'
    creative_template = 'creative-template'
    creative_transformers = 'creative-transformers'
    governance_aware_seller = 'governance-aware-seller'
    governance_delivery_monitor = 'governance-delivery-monitor'
    governance_spend_authority = 'governance-spend-authority'
    property_lists = 'property-lists'
    sales_broadcast_tv = 'sales-broadcast-tv'
    sales_catalog_driven = 'sales-catalog-driven'
    sales_dooh = 'sales-dooh'
    sales_exchange = 'sales-exchange'
    sales_guaranteed = 'sales-guaranteed'
    sales_non_guaranteed = 'sales-non-guaranteed'
    sales_proposal_mode = 'sales-proposal-mode'
    sales_retail_media = 'sales-retail-media'
    sales_streaming_tv = 'sales-streaming-tv'
    sales_social = 'sales-social'
    signal_marketplace = 'signal-marketplace'
    orchestrator_multi_agent = 'orchestrator-multi-agent'
    signal_owned = 'signal-owned'
    signed_requests = 'signed-requests'
    sponsored_intelligence = 'sponsored-intelligence'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var audience_sync
var brand_rights
var buyer_activation
var buyer_discovery
var buyer_monitoring
var buyer_negotiation
var buyer_recovery
var collection_lists
var content_standards
var creative_ad_server
var creative_generative
var creative_template
var creative_transformers
var governance_aware_seller
var governance_delivery_monitor
var governance_spend_authority
var orchestrator_multi_agent
var property_lists
var sales_broadcast_tv
var sales_catalog_driven
var sales_dooh
var sales_exchange
var sales_guaranteed
var sales_non_guaranteed
var sales_proposal_mode
var sales_retail_media
var sales_social
var sales_streaming_tv
var signal_marketplace
var signal_owned
var signed_requests
var sponsored_intelligence
class SponsoredIntelligence (**data: Any)
Expand source code
class SponsoredIntelligence(AdCPBaseModel):
    endpoint: Annotated[Endpoint, Field(description='SI agent endpoint configuration')]
    capabilities: Annotated[
        Capabilities,
        Field(
            description='Modalities, components, and commerce capabilities', title='SI Capabilities'
        ),
    ]
    brand_url: Annotated[
        AnyUrl | None, Field(description='URL to brand.json with colors, fonts, logos, tone')
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var brand_url : pydantic.networks.AnyUrl | None
var capabilities : Capabilities
var endpoint : Endpoint
var model_config

Inherited members

class SupportedProtocol (*args, **kwds)
Expand source code
class SupportedProtocol(StrEnum):
    media_buy = 'media_buy'
    signals = 'signals'
    governance = 'governance'
    sponsored_intelligence = 'sponsored_intelligence'
    creative = 'creative'
    brand = 'brand'
    measurement = 'measurement'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var brand
var creative
var governance
var measurement
var media_buy
var signals
var sponsored_intelligence
class Targeting (**data: Any)
Expand source code
class Targeting(AdCPBaseModel):
    geo_countries: Annotated[
        StrictBool | None,
        Field(description='Country-level targeting using ISO 3166-1 alpha-2 codes'),
    ] = None
    geo_regions: Annotated[
        StrictBool | GeoRegions | None,
        Field(
            description='ISO 3166-2 subdivision inclusion targeting. A legacy boolean is a coarse seller-wide declaration. Structured country/value entries are individually supported within the response scope, but do not promise joint composability or availability through the same execution route or account. Only Product.overlay_support supplies the binding set of executable targeting permissions for a configured Product.'
        ),
    ] = None
    geo_regions_exclude: Annotated[
        StrictBool | GeoRegionsExclude | None,
        Field(
            description='ISO 3166-2 subdivision exclusion targeting, declared independently from inclusion. Structured country/value entries are individually supported within the response scope, but do not promise joint composability or availability through the same execution route or account. Only Product.overlay_support supplies the binding set of executable targeting permissions for a configured Product; absence means buyers cannot infer exclusion support from geo_regions alone.'
        ),
    ] = None
    geo_metros: Annotated[
        GeoMetros | None,
        Field(
            description='Metro area targeting. Properties indicate which classification systems are supported.'
        ),
    ] = None
    geo_postal_areas: Annotated[
        GeoPostalAreas | None,
        Field(
            description='Declares supported postal area systems. Native support is keyed by ISO 3166-1 alpha-2 country with arrays of country-local postal systems. Deprecated country-fused boolean aliases may be included during migration.',
            title='Postal Area Support',
        ),
    ] = None
    geo_places: Annotated[
        dict[GeoPlaces1 | GeoPlaces2, GeoPlaces] | None,
        Field(
            description='Place targeting support keyed by collision-safe identifier system. Each system declares exact country-to-place-type combinations, accepted catalog versions, and a machine-readable resolver. Sellers MUST reject unsupported systems, country/type pairs, versions, and identifiers rather than silently dropping them.',
            min_length=1,
        ),
    ] = None
    age_restriction: Annotated[
        AgeRestriction | None,
        Field(description='Age restriction capabilities for compliance (alcohol, gambling)'),
    ] = None
    demographics: Annotated[
        Demographics | None,
        Field(
            description='Seller-wide discovery rollup for canonical demographic targeting. supported=true means at least one product implements the demographic targeting contract; it does not authorize demographic targeting on every product. Buyers MUST inspect Product.demographic_targeting for exact execution modes, bounds, intervals, and unknown-age behavior.'
        ),
    ] = None
    language: Annotated[
        StrictBool | Language | None,
        Field(
            description="Language-preference targeting support. A legacy boolean is a coarse declaration. The structured form can enumerate the exact canonical BCP 47 targeting ranges the seller accepts. Buyers MUST treat supported_languages as exact selectable values: a declared 'fr' does not by itself authorize a request for 'fr-CA'. Sellers MUST reject unsupported requested values rather than silently widening or dropping them."
        ),
    ] = None
    keyword_targets: Annotated[
        KeywordTargets | None,
        Field(
            description='Keyword targeting capabilities. Presence indicates support for targeting_overlay.keyword_targets and keyword_targets_add/remove in update_media_buy.'
        ),
    ] = None
    negative_keywords: Annotated[
        NegativeKeywords | None,
        Field(
            description='Negative keyword capabilities. Presence indicates support for targeting_overlay.negative_keywords and negative_keywords_add/remove in update_media_buy.'
        ),
    ] = None
    placement_selection: Annotated[
        StrictBool | None,
        Field(
            description='When true, seller-wide rollup indicating at least one product supports targeting_overlay.placement_selection. False or absence makes no product-level promise. Product.overlay_support and Product.placements remain authoritative for a selected product.'
        ),
    ] = None
    property_list: Annotated[
        StrictBool | None,
        Field(
            description='When true, seller-wide rollup indicating at least one product supports targeting_overlay.property_list inclusion targeting. False or absence makes no product-level promise. Product.overlay_support is authoritative.'
        ),
    ] = None
    property_list_exclude: Annotated[
        StrictBool | None,
        Field(
            description='When true, seller-wide rollup indicating at least one product supports targeting_overlay.property_list_exclude targeting. False or absence makes no product-level promise. Product.overlay_support is authoritative.'
        ),
    ] = None
    collection_list: Annotated[
        StrictBool | None,
        Field(
            description='When true, seller-wide rollup indicating at least one product supports targeting_overlay.collection_list inclusion targeting. False or absence makes no product-level promise. Product.overlay_support is authoritative.'
        ),
    ] = None
    collection_list_exclude: Annotated[
        StrictBool | None,
        Field(
            description='When true, seller-wide rollup indicating at least one product supports targeting_overlay.collection_list_exclude targeting. False or absence makes no product-level promise. Product.overlay_support is authoritative.'
        ),
    ] = None
    geo_proximity: Annotated[
        GeoProximity | None,
        Field(
            description='Proximity targeting capabilities from arbitrary coordinates via targeting_overlay.geo_proximity.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var age_restriction : AgeRestriction | None
var collection_list : bool | None
var collection_list_exclude : bool | None
var demographics : Demographics | None
var geo_countries : bool | None
var geo_metros : GeoMetros | None
var geo_places : dict[GeoPlaces1 | GeoPlaces2, GeoPlaces] | None
var geo_postal_areas : GeoPostalAreas | None
var geo_proximity : GeoProximity | None
var geo_regions : bool | GeoRegions | None
var geo_regions_exclude : bool | GeoRegionsExclude | None
var keyword_targets : KeywordTargets | None
var language : bool | Language | None
var model_config
var negative_keywords : NegativeKeywords | None
var placement_selection : bool | None
var property_list : bool | None
var property_list_exclude : bool | None

Inherited members

class Transport (**data: Any)
Expand source code
class Transport3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    type: Annotated[Type9, Field(description='Protocol transport type')]
    url: Annotated[AnyUrl, Field(description='Agent endpoint URL for this transport')]

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var type : Type9
var url : pydantic.networks.AnyUrl

Inherited members

class TrustedMatch (**data: Any)
Expand source code
class TrustedMatch(AdCPBaseModel):
    surfaces: Annotated[
        list[Surface] | None, Field(description='Surface types this seller supports via TMP.')
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var surfaces : list[Surface] | None

Inherited members

class Video (**data: Any)
Expand source code
class Video(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    formats: Annotated[
        list[str] | None, Field(description='Supported video formats (mp4, webm, etc.)')
    ] = None
    max_duration_seconds: Annotated[
        SchemaInt | None, Field(description='Maximum video duration')
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var formats : list[str] | None
var max_duration_seconds : int | None
var model_config

Inherited members

class Voice (**data: Any)
Expand source code
class Voice(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    provider: Annotated[
        str | None, Field(description='TTS provider (elevenlabs, openai, etc.)')
    ] = None
    voice_id: Annotated[str | None, Field(description='Brand voice identifier')] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var model_config
var provider : str | None
var voice_id : str | None

Inherited members

class WebhookSigning (**data: Any)
Expand source code
class WebhookSigning(AdCPBaseModel):
    supported: Annotated[
        StrictBool,
        Field(
            description='Whether this agent signs outbound webhooks with the AdCP RFC 9421 webhook profile. When false or absent, webhooks are delivered with legacy Bearer or HMAC-SHA256 auth only and receivers MUST NOT expect a Signature header. When the seller advertises mutating-webhook emission (i.e., `media_buy.reporting_delivery_methods` includes `webhook`, `media_buy.content_standards.supports_webhook_delivery` is true, `media_buy.relationship_notifications.supported` is true, `wholesale_feed_webhooks.supported` is true, `adcp.capability_changes.notifications.supported` is true, or `account.notifications.supported` is true), this MUST be `true` — emitting state-changing webhooks unsigned is a downgrade vector that lets an on-path attacker forge delivery callbacks. See `x-adcp-validation`.'
        ),
    ]
    profile: Annotated[
        Literal['adcp/webhook-signing/v1'] | None,
        Field(
            description='Identifier of the webhook-signing profile version the agent emits. Value MUST match the `tag=` parameter emitted in the RFC 9421 `Signature-Input` header (see docs/building/implementation/webhooks.mdx) so receivers can statically validate the declared profile against the on-wire tag. Closed enum; future profile revisions will extend this enum in a follow-up schema bump.'
        ),
    ] = None
    algorithms: Annotated[
        list[Algorithm] | None,
        Field(
            description="Signature algorithms this agent uses on outbound webhooks. 3.0 profile permits 'ed25519' and 'ecdsa-p256-sha256' only; other values are reserved for future profile versions and MUST NOT be emitted under adcp/webhook-signing/v1.",
            min_length=1,
        ),
    ] = None
    legacy_hmac_fallback: Annotated[
        StrictBool | None,
        Field(
            deprecated=True,
            description='Whether this agent will fall back to HMAC-SHA256 on the legacy push_notification_config.authentication, accounts[].notification_configs[].authentication, sync_principal.configuration.notification_configs[].authentication, or sync_agent_notification_configs.notification_configs[].authentication paths for receivers that have not adopted RFC 9421. Deprecated; removed in AdCP 4.0.',
        ),
    ] = False
    delivery_retry_horizon_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum elapsed time from the first delivery attempt during which this agent may retry the same webhook delivery. The publisher retains the immutable delivery-key-to-RFC-8785-JCS-payload binding and sufficient delivery state for at least this interval, and MUST NOT retry that key afterward. Receivers retain the matching payload binding and terminal publication proof for at least max(86400, this value) seconds in AdCP 3.x. Retries do not extend the horizon. A webhook-emitting AdCP 3.2 agent MUST populate this additive field; it remains schema-optional so existing 3.x capability documents stay valid. Minimum 86400 (24h), maximum 604800 (7d).',
            ge=86400,
            le=604800,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

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

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

Important

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

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

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

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

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

Ancestors

Class variables

var algorithms : list[Algorithm] | None
var delivery_retry_horizon_seconds : int | None
var legacy_hmac_fallback : bool | None
var model_config
var profile : Literal['adcp/webhook-signing/v1'] | None
var supported : bool

Inherited members