Module adcp.types.domains.account
Types the AdCP account schemas declare.
Importing from the domain says which variant you mean, where the flat
adcp.types namespace can only bind one class per name:
from adcp.types.domains.account import <Type>
A type this domain declares in more than one schema is not here: import
it from its own schema's module, adcp.types.domains.account.<schema>.
Nothing here is renamed.
Auto-generated from the generated domain tree. DO NOT EDIT MANUALLY. Generation date: 2026-10-04 18:45:11 UTC
Sub-modules
adcp.types.domains.account.get_account_financials_requestadcp.types.domains.account.get_account_financials_responseadcp.types.domains.account.list_account_changes_requestadcp.types.domains.account.list_account_changes_responseadcp.types.domains.account.list_accounts_requestadcp.types.domains.account.list_accounts_responseadcp.types.domains.account.report_usage_requestadcp.types.domains.account.report_usage_responseadcp.types.domains.account.sync_accounts_requestadcp.types.domains.account.sync_accounts_responseadcp.types.domains.account.sync_governance_requestadcp.types.domains.account.sync_governance_response
Classes
class Accounts (**data: Any)-
Expand source code
class Accounts(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) account: Annotated[ account_ref.AccountReference | None, Field( description='Settings-update key. When present, this entry targets an existing account by `account_id` (seller-owned account namespace) or natural key (buyer-declared account settings-update against a previously-provisioned account). Mutually exclusive with the flat `brand` + `operator` + `billing` provisioning trio. When `account` is present, the seller MUST NOT create a new account — entries that would otherwise trigger provisioning are rejected with `UNSUPPORTED_PROVISIONING`.' ), ] = None revision: Annotated[ SchemaInt | None, Field( description='Expected current account revision for optimistic concurrency in settings-update mode. Required whenever operator_identity is present; optional for existing non-identity settings updates. The seller MUST compare it atomically with the write, reject a mismatch with CONFLICT, and leave the account unchanged. Obtain it from list_accounts or the most recent sync_accounts result. Reads, dry runs, validation failures, and exact idempotency replays do not increment revision; every persisted settings or identity-change state transition does. MUST be absent in provisioning mode.', ge=1, ), ] = None operator_identity: Annotated[ operator_identity_1.OperatorIdentity | None, Field( description='Complete desired operator identity for settings-update mode. Omit this field to leave operator identity unchanged. When present, omission of operator_unit within the object removes the existing unit. Changing only operator_unit_1.name updates display metadata; changing operator_unit_1.id or adding/removing a unit rekeys the same account within the current operator. Changing operator requests an inter-entity handoff and MUST enter pending_approval until the seller verifies the current account authority, verified brand authorization, destination-operator acceptance, and any operator-scoped billing and grant transition. The seller MUST preserve account_id and account-scoped historical resources, MUST reject collisions without merging, and MUST apply no identity change if continuity cannot be preserved. MUST be accompanied by revision and MUST be absent in provisioning mode.' ), ] = None destination_billing_entity: Annotated[ business_entity.BusinessEntity | None, Field( description="Complete staged billing identity for the requested destination operator during an operator-domain handoff on an account whose billing party is operator. This value is write-only while approval is pending and MUST NOT replace or be echoed as the account's canonical billing_entity until the handoff applies atomically. Required by the protocol when an operator-billed account changes operator; otherwise MUST be absent. Requires operator_identity and revision and MUST be absent in provisioning mode." ), ] = None brand: Annotated[ brand_ref.BrandReference, Field( description='Brand reference identifying the advertiser. Required for **provisioning mode**; MUST be absent in settings-update mode. Only the BrandKey projection — `domain`, `brand_id`, and the canonicalized `countries[]` set — participates in account identity. Mutable or per-call BrandRef fields such as `industries`, `data_subject_contestation`, and `brand_kit_override` MUST NOT affect lookup, idempotency, or account creation. New 3.2 producers SHOULD send only the BrandKey fields; the broader BrandRef remains accepted on this existing 3.x task for compatibility.' ), ] operator: Annotated[ str, Field( description="Domain of the entity operating on the brand's behalf (e.g., 'pinnacle-media.com'). When the brand operates directly, this is the brand's domain. Verified against the brand's authorized_operators in brand.json. Required for **provisioning mode**; MUST be absent in settings-update mode.", pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', ), ] operator_unit: Annotated[ operator_unit_1.OperatorUnit | None, Field( description='Optional operator-owned business unit, agency seat, or platform account for provisioning mode. operator_unit_1.id participates in the natural key; name is mapping/display metadata. MUST be absent in settings-update mode.' ), ] = None currency: Annotated[ str | None, Field( description='Optional immutable ISO 4217 transaction currency for a currency-bound advertiser object. Consult `account.supported_account_currency_modes` before provisioning. When supplied, it participates in the natural key and all media buys on the account use it. Omit for per-media-buy currency selection. MUST be absent in settings-update mode.', pattern='^[A-Z]{3}$', ), ] = None timezone: Annotated[ str | None, Field( description='Immutable operational timezone selected for an account_fixed advertiser object. Required in provisioning mode when get_adcp_capabilities.account.timezone declares account_selection: buyer_selected, and the value MUST be one of supported_timezones. Omit for seller_fixed or seller_assigned modes. When supplied, it participates in the natural key. MUST be absent in settings-update mode.', min_length=1, ), ] = None billing: Annotated[ billing_party.BillingParty, Field( description='Who the seller invoices for this buyer–storefront account relationship. Required for **provisioning mode**; MUST be absent in settings-update mode (the invoiced party is fixed at provisioning time and cannot be changed via settings-update). This field does not select a payment rail, clearing intermediary, or per-media-buy settlement route.' ), ] billing_entity: Annotated[ business_entity.BusinessEntity | None, Field( description='Business entity details for the party responsible for payment. The agent provides this so the seller has the legal name, tax IDs, address, and bank details needed for formal B2B invoicing. Permitted in both modes — sellers MAY accept refinements in settings-update mode (e.g., updated bank details).' ), ] = None payment_terms: Annotated[ payment_terms_1.PaymentTerms | None, Field( description='Payment terms for this account. The seller must either accept these terms or reject the account — terms are never silently remapped. When omitted, the seller applies its default terms. Permitted in both modes.' ), ] = None sandbox: Annotated[ StrictBool | None, Field( description='When true, provision this as a sandbox account with no real platform calls or billing. Only applicable to buyer-declared accounts (require_operator_auth: false) in provisioning mode. For account-id namespaces, sandbox accounts are pre-existing test accounts discovered via list_accounts or supplied out-of-band.' ), ] = None preferred_reporting_protocol: Annotated[ cloud_storage_protocol.CloudStorageProtocol | None, Field( description="Buyer's preferred cloud storage protocol for offline reporting delivery. The seller provisions the account's reporting_bucket using this protocol if supported. When omitted, the seller chooses from its supported offline_delivery_protocols. Only meaningful when the seller's reporting_delivery_methods includes 'offline'." ), ] = None reporting_delivery_configs: Annotated[ list[reporting_delivery_config.ReportingDeliveryConfiguration] | None, Field( description="Caller-owned desired state for durable reporting delivery on this account. Declarative replacement is scoped to (authenticated caller, resolved account): omission leaves that caller's set unchanged; [] deactivates that caller's set and starts grant revocation; another caller's entries MUST NOT be read, replaced, or deleted. Entries are keyed by immutable (delivery_config_id, delivery_config_version); duplicate tuples MUST reject the entire account entry, and reusing a tuple with changed content MUST be rejected. Each generation binds the exact report_definition_id advertised by its offering. destination.mode provision asks the seller to verify caller disclosure authority and destination/recipient control from non-secret provider coordinates; destination.mode existing reuses a caller-scoped immutable destination-generation reference, including one registered through sync_agent_configuration. The account configuration independently authorizes disclosure for this feed and scope, so possession of a reusable reference is never account authority. Unknown, unauthorized, and cross-caller refs MUST be indistinguishable. Credentials never transit AdCP, including nested extension fields. Permitted in both provisioning and settings-update modes. Sellers accepting this field MUST advertise media_buy.reporting_delivery in experimental_features and echo resolved secret-free state on sync_accounts and list_accounts.", max_length=16, ), ] = None notification_configs: Annotated[ list[notification_config.NotificationConfig] | None, Field( description='Account-level webhook subscriptions for notifications whose lifecycle outlives any single media buy (`creative.status_changed`, optional `creative.assignment_changed`, `indicators.changed`, `creative.purged`, `account.status_changed`, wholesale feed change payloads, and future account-anchored resource events after those event types are added to `notification-config.json`). Indicator and assignment registrations are prospective: activation does not replay current conditions, so buyers establish a complete baseline through `get_media_buys` by enumerating known IDs or requesting every status and exhausting pagination, without an indicator filter. Durable account lifecycle transitions such as later `payment_required`, `suspended`, `closed`, or recovery to `active` use `account.status_changed` on this surface; the one-shot `sync_accounts.push_notification_config` channel remains scoped to the async result of the original provisioning task. Declarative replace semantics: when this field is present, the buyer sends the full desired array and the seller replaces the account\'s current set with that array, keyed by account-scoped `subscriber_id`. Omit this field to leave existing subscribers unchanged; send `[]` to remove all subscribers. Re-sending an existing `subscriber_id` for the account replaces that subscriber\'s config rather than creating a duplicate; persisted entries whose `subscriber_id` does not appear in the sent array are removed, so the seller MUST NOT merge the new array with persisted state. Paused entries (`active: false`) use the same replacement semantics; a buyer that wants to preserve a paused subscriber MUST re-include it with `active: false`. Duplicate `subscriber_id` values within one submitted array are rejected. Permitted in both provisioning and settings-update modes. Each entry registers a URL, the event types the subscriber wants, and optional legacy auth — see [`notification-config.json`](/schemas/core/notification-config.json). The seller MUST echo applied state on the response and on `list_accounts` reads, with `authentication.credentials` omitted (write-only). Sellers MUST reject entries whose `event_types` include any type whose contract anchors at a media buy or below (today: `scheduled`, `final`, `delayed`, `adjusted`, `window_update`, `impairment`) or at the agent (today: `capabilities.changed`) as per-account validation failures with `INVALID_REQUEST` or `VALIDATION_ERROR` and `error.field` pointing at the invalid `event_types` entry — those events do not belong on this surface. Wholesale feed webhook registrations carry the actual change payload in `/schemas/core/wholesale-feed-webhook.json`; canonical product subscribers repair through `list_products(if_feed_version)`, legacy product subscribers through `get_products(if_wholesale_feed_version)`, and signal subscribers through `get_signals(if_wholesale_feed_version)`. Account status change registrations carry the invalidation payload in `/schemas/core/account-status-changed-webhook.json`; receivers use `list_accounts` to repair or reconcile. This is distinct from sync_catalogs, which manages buyer-provided campaign input feeds on a seller account.\n\nActivation proof: before activating a new or changed active subscriber, the seller MUST validate the URL, complete the account-level webhook proof-of-control challenge, and only then persist or expose the subscriber as `active: true`. For `account.status_changed`, sellers MUST assign `account_id` before completing proof so subsequent status transitions can identify the account and be repaired through `list_accounts`, even when external approval remains pending. A valid existing proof for the same `(account_id, subscriber_id, normalized url, authentication mode/credential binding, normalized event_types)` tuple MAY be reused; changing any element of that tuple requires fresh proof. The challenge POST itself MUST be signed with the seller\'s RFC 9421 webhook profile key and MUST include seller_agent_url, delivery_auth, and event_types so the receiver can verify the pending registration before echoing the challenge. New signers use `adcp_use: "request-signing"`; deprecated `webhook-signing` keys remain accepted during the compatibility window. Entries sent with `active: false` may skip only the outbound proof challenge while inactive; sellers MUST still enforce URL parsing, HTTPS, hostname normalization, and reserved-range rejection at write time, and those entries MUST NOT receive fires until reactivated. If proof fails or times out, the seller rejects the account entry with `action: "failed"`, leaves the prior notification_configs[] set unchanged, and reports `VALIDATION_ERROR` (or `INVALID_REQUEST` for malformed URLs) at the failing `notification_configs[j].url` field.\n\n**Cap rationale:** `maxItems: 16` is a practical fan-out cap (governance + buyer ingestion + audit bus + dx team + a few partner hooks). The cap exists to prevent unbounded subscriber arrays in storage and to bound the seller\'s per-event fan-out work. Sellers that hit the cap with legitimate subscribers should surface this on the protocol roadmap rather than work around it.', max_length=16, ), ] = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2 | Nonevar billing : BillingPartyvar billing_entity : BusinessEntity | Nonevar brand : BrandReferencevar currency : str | Nonevar destination_billing_entity : BusinessEntity | Nonevar model_configvar notification_configs : list[NotificationConfig] | Nonevar operator : strvar operator_identity : OperatorIdentity | Nonevar operator_unit : OperatorUnit | Nonevar payment_terms : PaymentTerms | Nonevar preferred_reporting_protocol : CloudStorageProtocol | Nonevar reporting_delivery_configs : list[ReportingDeliveryConfiguration] | Nonevar revision : int | Nonevar sandbox : bool | Nonevar timezone : str | None
Inherited members
class Accounts1 (**data: Any)-
Expand source code
class Accounts1(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) account: Annotated[ account_ref.AccountReference, Field( description='Settings-update key. When present, this entry targets an existing account by `account_id` (seller-owned account namespace) or natural key (buyer-declared account settings-update against a previously-provisioned account). Mutually exclusive with the flat `brand` + `operator` + `billing` provisioning trio. When `account` is present, the seller MUST NOT create a new account — entries that would otherwise trigger provisioning are rejected with `UNSUPPORTED_PROVISIONING`.' ), ] revision: Annotated[ SchemaInt | None, Field( description='Expected current account revision for optimistic concurrency in settings-update mode. Required whenever operator_identity is present; optional for existing non-identity settings updates. The seller MUST compare it atomically with the write, reject a mismatch with CONFLICT, and leave the account unchanged. Obtain it from list_accounts or the most recent sync_accounts result. Reads, dry runs, validation failures, and exact idempotency replays do not increment revision; every persisted settings or identity-change state transition does. MUST be absent in provisioning mode.', ge=1, ), ] = None operator_identity: Annotated[ operator_identity_1.OperatorIdentity | None, Field( description='Complete desired operator identity for settings-update mode. Omit this field to leave operator identity unchanged. When present, omission of operator_unit within the object removes the existing unit. Changing only operator_unit_1.name updates display metadata; changing operator_unit_1.id or adding/removing a unit rekeys the same account within the current operator. Changing operator requests an inter-entity handoff and MUST enter pending_approval until the seller verifies the current account authority, verified brand authorization, destination-operator acceptance, and any operator-scoped billing and grant transition. The seller MUST preserve account_id and account-scoped historical resources, MUST reject collisions without merging, and MUST apply no identity change if continuity cannot be preserved. MUST be accompanied by revision and MUST be absent in provisioning mode.' ), ] = None destination_billing_entity: Annotated[ business_entity.BusinessEntity | None, Field( description="Complete staged billing identity for the requested destination operator during an operator-domain handoff on an account whose billing party is operator. This value is write-only while approval is pending and MUST NOT replace or be echoed as the account's canonical billing_entity until the handoff applies atomically. Required by the protocol when an operator-billed account changes operator; otherwise MUST be absent. Requires operator_identity and revision and MUST be absent in provisioning mode." ), ] = None brand: Annotated[ brand_ref.BrandReference | None, Field( description='Brand reference identifying the advertiser. Required for **provisioning mode**; MUST be absent in settings-update mode. Only the BrandKey projection — `domain`, `brand_id`, and the canonicalized `countries[]` set — participates in account identity. Mutable or per-call BrandRef fields such as `industries`, `data_subject_contestation`, and `brand_kit_override` MUST NOT affect lookup, idempotency, or account creation. New 3.2 producers SHOULD send only the BrandKey fields; the broader BrandRef remains accepted on this existing 3.x task for compatibility.' ), ] = None operator: Annotated[ str | None, Field( description="Domain of the entity operating on the brand's behalf (e.g., 'pinnacle-media.com'). When the brand operates directly, this is the brand's domain. Verified against the brand's authorized_operators in brand.json. Required for **provisioning mode**; MUST be absent in settings-update mode.", pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', ), ] = None operator_unit: Annotated[ operator_unit_1.OperatorUnit | None, Field( description='Optional operator-owned business unit, agency seat, or platform account for provisioning mode. operator_unit_1.id participates in the natural key; name is mapping/display metadata. MUST be absent in settings-update mode.' ), ] = None currency: Annotated[ str | None, Field( description='Optional immutable ISO 4217 transaction currency for a currency-bound advertiser object. Consult `account.supported_account_currency_modes` before provisioning. When supplied, it participates in the natural key and all media buys on the account use it. Omit for per-media-buy currency selection. MUST be absent in settings-update mode.', pattern='^[A-Z]{3}$', ), ] = None timezone: Annotated[ str | None, Field( description='Immutable operational timezone selected for an account_fixed advertiser object. Required in provisioning mode when get_adcp_capabilities.account.timezone declares account_selection: buyer_selected, and the value MUST be one of supported_timezones. Omit for seller_fixed or seller_assigned modes. When supplied, it participates in the natural key. MUST be absent in settings-update mode.', min_length=1, ), ] = None billing: Annotated[ billing_party.BillingParty | None, Field( description='Who the seller invoices for this buyer–storefront account relationship. Required for **provisioning mode**; MUST be absent in settings-update mode (the invoiced party is fixed at provisioning time and cannot be changed via settings-update). This field does not select a payment rail, clearing intermediary, or per-media-buy settlement route.' ), ] = None billing_entity: Annotated[ business_entity.BusinessEntity | None, Field( description='Business entity details for the party responsible for payment. The agent provides this so the seller has the legal name, tax IDs, address, and bank details needed for formal B2B invoicing. Permitted in both modes — sellers MAY accept refinements in settings-update mode (e.g., updated bank details).' ), ] = None payment_terms: Annotated[ payment_terms_1.PaymentTerms | None, Field( description='Payment terms for this account. The seller must either accept these terms or reject the account — terms are never silently remapped. When omitted, the seller applies its default terms. Permitted in both modes.' ), ] = None sandbox: Annotated[ StrictBool | None, Field( description='When true, provision this as a sandbox account with no real platform calls or billing. Only applicable to buyer-declared accounts (require_operator_auth: false) in provisioning mode. For account-id namespaces, sandbox accounts are pre-existing test accounts discovered via list_accounts or supplied out-of-band.' ), ] = None preferred_reporting_protocol: Annotated[ cloud_storage_protocol.CloudStorageProtocol | None, Field( description="Buyer's preferred cloud storage protocol for offline reporting delivery. The seller provisions the account's reporting_bucket using this protocol if supported. When omitted, the seller chooses from its supported offline_delivery_protocols. Only meaningful when the seller's reporting_delivery_methods includes 'offline'." ), ] = None reporting_delivery_configs: Annotated[ list[reporting_delivery_config.ReportingDeliveryConfiguration] | None, Field( description="Caller-owned desired state for durable reporting delivery on this account. Declarative replacement is scoped to (authenticated caller, resolved account): omission leaves that caller's set unchanged; [] deactivates that caller's set and starts grant revocation; another caller's entries MUST NOT be read, replaced, or deleted. Entries are keyed by immutable (delivery_config_id, delivery_config_version); duplicate tuples MUST reject the entire account entry, and reusing a tuple with changed content MUST be rejected. Each generation binds the exact report_definition_id advertised by its offering. destination.mode provision asks the seller to verify caller disclosure authority and destination/recipient control from non-secret provider coordinates; destination.mode existing reuses a caller-scoped immutable destination-generation reference, including one registered through sync_agent_configuration. The account configuration independently authorizes disclosure for this feed and scope, so possession of a reusable reference is never account authority. Unknown, unauthorized, and cross-caller refs MUST be indistinguishable. Credentials never transit AdCP, including nested extension fields. Permitted in both provisioning and settings-update modes. Sellers accepting this field MUST advertise media_buy.reporting_delivery in experimental_features and echo resolved secret-free state on sync_accounts and list_accounts.", max_length=16, ), ] = None notification_configs: Annotated[ list[notification_config.NotificationConfig] | None, Field( description='Account-level webhook subscriptions for notifications whose lifecycle outlives any single media buy (`creative.status_changed`, optional `creative.assignment_changed`, `indicators.changed`, `creative.purged`, `account.status_changed`, wholesale feed change payloads, and future account-anchored resource events after those event types are added to `notification-config.json`). Indicator and assignment registrations are prospective: activation does not replay current conditions, so buyers establish a complete baseline through `get_media_buys` by enumerating known IDs or requesting every status and exhausting pagination, without an indicator filter. Durable account lifecycle transitions such as later `payment_required`, `suspended`, `closed`, or recovery to `active` use `account.status_changed` on this surface; the one-shot `sync_accounts.push_notification_config` channel remains scoped to the async result of the original provisioning task. Declarative replace semantics: when this field is present, the buyer sends the full desired array and the seller replaces the account\'s current set with that array, keyed by account-scoped `subscriber_id`. Omit this field to leave existing subscribers unchanged; send `[]` to remove all subscribers. Re-sending an existing `subscriber_id` for the account replaces that subscriber\'s config rather than creating a duplicate; persisted entries whose `subscriber_id` does not appear in the sent array are removed, so the seller MUST NOT merge the new array with persisted state. Paused entries (`active: false`) use the same replacement semantics; a buyer that wants to preserve a paused subscriber MUST re-include it with `active: false`. Duplicate `subscriber_id` values within one submitted array are rejected. Permitted in both provisioning and settings-update modes. Each entry registers a URL, the event types the subscriber wants, and optional legacy auth — see [`notification-config.json`](/schemas/core/notification-config.json). The seller MUST echo applied state on the response and on `list_accounts` reads, with `authentication.credentials` omitted (write-only). Sellers MUST reject entries whose `event_types` include any type whose contract anchors at a media buy or below (today: `scheduled`, `final`, `delayed`, `adjusted`, `window_update`, `impairment`) or at the agent (today: `capabilities.changed`) as per-account validation failures with `INVALID_REQUEST` or `VALIDATION_ERROR` and `error.field` pointing at the invalid `event_types` entry — those events do not belong on this surface. Wholesale feed webhook registrations carry the actual change payload in `/schemas/core/wholesale-feed-webhook.json`; canonical product subscribers repair through `list_products(if_feed_version)`, legacy product subscribers through `get_products(if_wholesale_feed_version)`, and signal subscribers through `get_signals(if_wholesale_feed_version)`. Account status change registrations carry the invalidation payload in `/schemas/core/account-status-changed-webhook.json`; receivers use `list_accounts` to repair or reconcile. This is distinct from sync_catalogs, which manages buyer-provided campaign input feeds on a seller account.\n\nActivation proof: before activating a new or changed active subscriber, the seller MUST validate the URL, complete the account-level webhook proof-of-control challenge, and only then persist or expose the subscriber as `active: true`. For `account.status_changed`, sellers MUST assign `account_id` before completing proof so subsequent status transitions can identify the account and be repaired through `list_accounts`, even when external approval remains pending. A valid existing proof for the same `(account_id, subscriber_id, normalized url, authentication mode/credential binding, normalized event_types)` tuple MAY be reused; changing any element of that tuple requires fresh proof. The challenge POST itself MUST be signed with the seller\'s RFC 9421 webhook profile key and MUST include seller_agent_url, delivery_auth, and event_types so the receiver can verify the pending registration before echoing the challenge. New signers use `adcp_use: "request-signing"`; deprecated `webhook-signing` keys remain accepted during the compatibility window. Entries sent with `active: false` may skip only the outbound proof challenge while inactive; sellers MUST still enforce URL parsing, HTTPS, hostname normalization, and reserved-range rejection at write time, and those entries MUST NOT receive fires until reactivated. If proof fails or times out, the seller rejects the account entry with `action: "failed"`, leaves the prior notification_configs[] set unchanged, and reports `VALIDATION_ERROR` (or `INVALID_REQUEST` for malformed URLs) at the failing `notification_configs[j].url` field.\n\n**Cap rationale:** `maxItems: 16` is a practical fan-out cap (governance + buyer ingestion + audit bus + dx team + a few partner hooks). The cap exists to prevent unbounded subscriber arrays in storage and to bound the seller\'s per-event fan-out work. Sellers that hit the cap with legitimate subscribers should surface this on the protocol roadmap rather than work around it.', max_length=16, ), ] = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2var billing : BillingParty | Nonevar billing_entity : BusinessEntity | Nonevar brand : BrandReference | Nonevar currency : str | Nonevar destination_billing_entity : BusinessEntity | Nonevar model_configvar notification_configs : list[NotificationConfig] | Nonevar operator : str | Nonevar operator_identity : OperatorIdentity | Nonevar operator_unit : OperatorUnit | Nonevar payment_terms : PaymentTerms | Nonevar preferred_reporting_protocol : CloudStorageProtocol | Nonevar reporting_delivery_configs : list[ReportingDeliveryConfiguration] | Nonevar revision : int | Nonevar sandbox : bool | Nonevar timezone : str | None
Inherited members
class Authentication (**data: Any)-
Expand source code
class Authentication(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) schemes: Annotated[ list[Literal['Bearer']], Field( description='The seller authenticates outbound check_governance calls with the registered Bearer credential. Other shared webhook authentication schemes are not valid for this agent-to-agent call.', max_length=1, min_length=1, ), ] credentials: Annotated[ str, Field(description='Authentication credential (e.g., Bearer token).', min_length=32) ]Base model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var credentials : strvar model_configvar schemes : list[typing.Literal['Bearer']]
Inherited members
class Balance (**data: Any)-
Expand source code
class Balance(AdcpVersionEnvelope): model_config = ConfigDict(extra='allow') available: Annotated[float, Field(ge=0)] last_top_up: LastTopUp | None = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var available : floatvar last_top_up : LastTopUp | Nonevar model_config
Inherited members
class Credit (**data: Any)-
Expand source code
class Credit(AdcpVersionEnvelope): model_config = ConfigDict(extra='allow') credit_limit: Annotated[float, Field(ge=0)] available_credit: float utilization_percent: Annotated[float, Field(ge=0, le=100)] | None = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var available_credit : floatvar credit_limit : floatvar model_configvar utilization_percent : float | None
Inherited members
class CreditLimit (**data: Any)-
Expand source code
class CreditLimit(AdcpVersionEnvelope): model_config = ConfigDict(extra='allow') amount: Annotated[float, Field(ge=0)] currency: Annotated[str, StringConstraints(pattern='^[A-Z]{3}$')]Base model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var amount : floatvar currency : strvar model_config
Inherited members
class GetAccountFinancialsRequest (**data: Any)-
Expand source code
class GetAccountFinancialsRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) account: Annotated[ account_ref.AccountReference, Field(description='Account to query financials for. Must be an operator-billed account.'), ] period: Annotated[ date_range.DateRange | None, Field( description='Date range for the spend summary. Defaults to the current billing cycle if omitted.' ), ] = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe request message of a task in the pinned bundle's task registry.
A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is.
issubclass(model, AdcpRequest)is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.Each accessor returns the field's value, or
Nonewhen this tool's schema declares no such field. Only 49 of the 87 request schemas declare anaccountand only 43 anidempotency_key, so asking the request is what replacesgetattr(req, "account", None)againstAnyat the boundary.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpRequest
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar model_configvar period : DateRange | None
Inherited members
class GetAccountFinancialsResponse1 (**data: Any)-
Expand source code
class GetAccountFinancialsResponse1(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope): model_config = ConfigDict(extra='allow') account: account_ref_1.AccountReference currency: Annotated[str, StringConstraints(pattern='^[A-Z]{3}$')] period: date_range_1.DateRange timezone: str spend: Spend | None = None credit: Credit | None = None balance: Balance | None = None payment_status: Literal['current', 'past_due', 'suspended'] | None = None payment_terms: payment_terms_1.PaymentTerms | None = None invoices: list[Invoice] | None = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe response message of a task in the pinned bundle's task registry.
A consumer holding one can route on task state, pick up an async
task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2var balance : Balance | Nonevar context : ContextObject | Nonevar credit : Credit | Nonevar currency : strvar ext : ExtensionObject | Nonevar invoices : list[Invoice] | Nonevar model_configvar payment_status : Literal['current', 'past_due', 'suspended'] | Nonevar payment_terms : PaymentTerms | Nonevar period : DateRangevar spend : Spend | Nonevar timezone : str
Inherited members
class GetAccountFinancialsResponse2 (**data: Any)-
Expand source code
class GetAccountFinancialsResponse2(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope): model_config = ConfigDict(extra='allow') errors: Annotated[list[error_1.Error], Field(min_length=1)] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe response message of a task in the pinned bundle's task registry.
A consumer holding one can route on task state, pick up an async
task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar errors : list[Error]var ext : ExtensionObject | Nonevar model_config
Inherited members
class Invoice (**data: Any)-
Expand source code
class Invoice(AdcpVersionEnvelope): model_config = ConfigDict(extra='allow') invoice_id: str period: date_range_1.DateRange | None = None amount: Annotated[float, Field(ge=0)] status: Literal['draft', 'issued', 'paid', 'past_due', 'void'] due_date: date | None = None paid_date: date | None = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var amount : floatvar due_date : datetime.date | Nonevar invoice_id : strvar model_configvar paid_date : datetime.date | Nonevar period : DateRange | Nonevar status : Literal['draft', 'issued', 'paid', 'past_due', 'void']
Inherited members
class Kind (*args, **kwds)-
Expand source code
class Kind(StrEnum): seller = 'seller' connected_platform = 'connected_platform'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var connected_platformvar seller
class LastTopUp (**data: Any)-
Expand source code
class LastTopUp(AdcpVersionEnvelope): model_config = ConfigDict(extra='allow') amount: Annotated[float, Field(ge=0)] date: dateBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var amount : floatvar date : datetime.datevar model_config
Inherited members
class ListAccountChangesRequest (**data: Any)-
Expand source code
class ListAccountChangesRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) account: Annotated[ account_ref.AccountReference, Field( description='Account whose change feed to read. The resolved account and returned cursor are bound to the authenticated principal.' ), ] cursor: Annotated[ str | None, Field( description='Opaque checkpoint returned by a prior call using the same authenticated principal, authorization scope epoch, account, and normalized filters. Returns changes strictly after the scanned high-water represented by this value. Sellers MUST reject reuse under a different principal, account, or filter set with INVALID_REQUEST at field cursor; an authorization-scope epoch change returns CURSOR_EXPIRED and requires snapshot rebootstrap.', max_length=4096, min_length=1, ), ] = None starting_position: Annotated[ StartingPosition | None, Field( description='Initial position when cursor is absent. Mutually exclusive with cursor; sellers enforce this semantic rule at runtime so the emitted MCP input schema can remain a plain root object. earliest intentionally begins at the oldest retained change. latest returns a checkpoint at the current seller-ingestion high-water and is used before a race-free snapshot bootstrap.' ), ] = StartingPosition.earliest resource_types: Annotated[ list[ResourceType] | None, Field( description='Optional exact resource-type filter. The cursor is bound to the normalized filter. Unknown resource types are allowed for forward compatibility.', max_length=50, min_length=1, ), ] = None max_results: Annotated[ SchemaInt | None, Field( description='Maximum changes to return. Sellers still scan through nonmatching records and advance the returned cursor.', ge=1, le=100, ), ] = 50 context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe request message of a task in the pinned bundle's task registry.
A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is.
issubclass(model, AdcpRequest)is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.Each accessor returns the field's value, or
Nonewhen this tool's schema declares no such field. Only 49 of the 87 request schemas declare anaccountand only 43 anidempotency_key, so asking the request is what replacesgetattr(req, "account", None)againstAnyat the boundary.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpRequest
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2var context : ContextObject | Nonevar cursor : str | Nonevar ext : ExtensionObject | Nonevar max_results : int | Nonevar model_configvar resource_types : list[ResourceType] | Nonevar starting_position : StartingPosition | None
Inherited members
class ListAccountChangesResponse (**data: Any)-
Expand source code
class ListAccountChangesResponse(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope): model_config = ConfigDict( extra='allow', ) changes: Annotated[ list[account_change.AccountChange] | None, Field( description='Matching changes in oldest-first total account order. Timestamps are descriptive and do not define this order.', max_length=100, ), ] = None cursor: Annotated[ str | None, Field( description='Opaque checkpoint strictly after the high-water scanned by this page. Always persist this value, including when changes is empty or has_more is false. A filtered empty page still advances past scanned nonmatching records.', max_length=4096, min_length=1, ), ] = None has_more: Annotated[ StrictBool | None, Field( description='True when more retained matching changes were available at generation time. False means caught up to seller ingestion, not necessarily to an unavailable or delayed connected source.' ), ] = None available_since: Annotated[ AwareDatetime | None, Field( description='Oldest time for which the seller currently retains change records for this account and caller. The capability guarantees at least 90 days after adoption; pre-adoption history is not fabricated.' ), ] = None generated_at: Annotated[ AwareDatetime | None, Field( description='Seller time when this page and its source-coverage watermarks were generated.' ), ] = None source_coverage: Annotated[ list[SourceCoverageItem] | None, Field( description='Account-specific feed and connector coverage. Buyers use this to distinguish feed catch-up from upstream freshness. Omission means no additional connected-source coverage is declared.', max_length=50, ), ] = None errors: list[error.Error] | None = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None status: Status22 @model_validator(mode='after') def _require_schema_required_group(self) -> ListAccountChangesResponse: # ``required`` asks whether the caller supplied the field, which is what # model_fields_set answers. An explicit null is a supplied value — on a # mutation input it is the command to clear — and a default the caller # never sent is not. for group in (('status', 'changes', 'cursor', 'has_more', 'available_since', 'generated_at'), ('status', 'adcp_error', 'errors'),): if all(name in self.model_fields_set for name in group): return self raise ValueError( 'ListAccountChangesResponse requires at least one of these field groups: status+changes+cursor+has_more+available_since+generated_at | status+adcp_error+errors' )The response message of a task in the pinned bundle's task registry.
A consumer holding one can route on task state, pick up an async
task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var available_since : pydantic.types.AwareDatetime | Nonevar changes : list[AccountChange] | Nonevar context : ContextObject | Nonevar cursor : str | Nonevar errors : list[Error] | Nonevar ext : ExtensionObject | Nonevar generated_at : pydantic.types.AwareDatetime | Nonevar has_more : bool | Nonevar model_configvar source_coverage : list[SourceCoverageItem] | Nonevar status : Status22
Inherited members
class ListAccountsRequest (**data: Any)-
Expand source code
class ListAccountsRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) account: Annotated[ account_ref.AccountReference | None, Field( description='Optional exact account filter. Use `account_id` to retrieve one known seller/storefront account, or the complete natural key (`brand` + `operator` + optional `operator_unit`, fixed `currency`, buyer-selected account `timezone`, and `sandbox`) for buyer-declared accounts. When present, the seller returns only matching accounts visible to the authenticated caller.' ), ] = None status: Annotated[ Status | None, Field(description='Filter accounts by status. Omit to return accounts in all statuses.'), ] = None pagination: pagination_request.PaginationRequest | None = None sandbox: Annotated[ StrictBool | None, Field( description='Filter by sandbox status. true returns only sandbox accounts, false returns only production accounts. Omit to return all accounts. Primarily used with account-id namespaces where sandbox accounts are pre-existing test accounts on the platform.' ), ] = None include_webhook_activity: Annotated[ StrictBool | None, Field( description='When true, request recent webhook delivery attempts for each returned account in account.webhook_activity[]. Sellers MAY omit webhook_activity if they do not expose this debug log; when present, three-state semantics match the shared webhook_activity[] contract.' ), ] = False webhook_activity_limit: Annotated[ SchemaInt | None, Field( description='Maximum number of webhook_activity[] records to return per account when include_webhook_activity is true.', ge=1, le=200, ), ] = 50 context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe request message of a task in the pinned bundle's task registry.
A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is.
issubclass(model, AdcpRequest)is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.Each accessor returns the field's value, or
Nonewhen this tool's schema declares no such field. Only 49 of the 87 request schemas declare anaccountand only 43 anidempotency_key, so asking the request is what replacesgetattr(req, "account", None)againstAnyat the boundary.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpRequest
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2 | Nonevar context : ContextObject | Nonevar ext : ExtensionObject | Nonevar include_webhook_activity : bool | Nonevar model_configvar pagination : PaginationRequest | Nonevar sandbox : bool | Nonevar status : Status | Nonevar webhook_activity_limit : int | None
Inherited members
class ListAccountsResponse (**data: Any)-
Expand source code
class ListAccountsResponse(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope): model_config = ConfigDict( extra='allow', ) accounts: Annotated[ list[account_with_authorization.AccountWithAuthorization], Field( description='Array of accounts accessible to the authenticated agent. Each entry is the full Account object plus optional authorization. Buyer-declared entries include brand, operator, and any operator_unit, fixed currency, buyer-selected account timezone, and sandbox qualifiers so the natural AccountRef round-trips after a cold start.' ), ] errors: Annotated[ list[error.Error] | None, Field(description='Task-specific errors and warnings') ] = None pagination: pagination_response.PaginationResponse | None = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe response message of a task in the pinned bundle's task registry.
A consumer holding one can route on task state, pick up an async
task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var accounts : list[AccountWithAuthorization]var context : ContextObject | Nonevar errors : list[Error] | Nonevar ext : ExtensionObject | Nonevar model_configvar pagination : PaginationResponse | None
Inherited members
class ReportUsageRequest (**data: Any)-
Expand source code
class ReportUsageRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) idempotency_key: Annotated[ str, Field( description='Client-generated unique key for this request. If a request with the same key has already been accepted, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request. Prevents duplicate billing on retries.' ), ] reporting_period: Annotated[ datetime_range.DatetimeRange, Field( description='The time range covered by this usage report. Applies to all records in the request.' ), ] usage: Annotated[ list[UsageItem], Field( description='One or more usage records. Each record is self-contained: it carries its own account, allowing a single request to span multiple accounts.', min_length=1, ), ] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe request message of a task in the pinned bundle's task registry.
A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is.
issubclass(model, AdcpRequest)is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.Each accessor returns the field's value, or
Nonewhen this tool's schema declares no such field. Only 49 of the 87 request schemas declare anaccountand only 43 anidempotency_key, so asking the request is what replacesgetattr(req, "account", None)againstAnyat the boundary.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpRequest
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar idempotency_key : strvar model_configvar reporting_period : DatetimeRangevar usage : list[UsageItem]
Inherited members
class ReportUsageResponse (**data: Any)-
Expand source code
class ReportUsageResponse(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope): model_config = ConfigDict( extra='allow', ) accepted: Annotated[ SchemaInt, Field(description='Number of usage records successfully stored.', ge=0) ] errors: Annotated[ list[error.Error] | None, Field( description="Validation errors for individual records. The field property identifies which record failed (e.g., 'usage[1].pricing_option_id')." ), ] = None sandbox: Annotated[ StrictBool | None, Field(description='When true, the account is a sandbox account and no billing occurred.'), ] = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe response message of a task in the pinned bundle's task registry.
A consumer holding one can route on task state, pick up an async
task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var accepted : intvar context : ContextObject | Nonevar errors : list[Error] | Nonevar ext : ExtensionObject | Nonevar model_configvar sandbox : bool | None
Inherited members
class Setup (**data: Any)-
Expand source code
class Setup(AdcpVersionEnvelope): model_config = ConfigDict(extra='allow') url: AnyUrl | None = None message: str expires_at: AwareDatetime | None = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var expires_at : pydantic.types.AwareDatetime | Nonevar message : strvar model_configvar url : pydantic.networks.AnyUrl | None
Inherited members
class SourceCoverageItem (**data: Any)-
Expand source code
class SourceCoverageItem(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) source_id: Annotated[ str, Field(description='Opaque seller or connection reference.', max_length=255) ] kind: Kind status: Annotated[ Status, Field( description='Connector freshness classification. For connected_platform, current means last_successful_sync_at is no older than stale_after_seconds at generated_at and the seller knows of no ingestion gap; delayed means that threshold is exceeded or a gap is known.' ), ] coverage_start: Annotated[ AwareDatetime | None, Field( description='Earliest upstream time covered by this source after connection or retention limits.' ), ] = None observed_through: Annotated[ AwareDatetime | None, Field(description='Latest upstream point the seller has successfully observed.'), ] = None last_successful_sync_at: AwareDatetime | None = None stale_after_seconds: Annotated[ SchemaInt | None, Field( description='Maximum age of last_successful_sync_at at generated_at for this connected source to self-classify as current. Required by the protocol contract whenever a connected source reports current.', ge=1, le=2592000, ), ] = None resource_types: Annotated[list[ResourceType], Field(max_length=50)]Base model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var coverage_start : pydantic.types.AwareDatetime | Nonevar kind : Kindvar last_successful_sync_at : pydantic.types.AwareDatetime | Nonevar model_configvar observed_through : pydantic.types.AwareDatetime | Nonevar resource_types : list[ResourceType]var source_id : strvar stale_after_seconds : int | Nonevar status : Status
Inherited members
class Spend (**data: Any)-
Expand source code
class Spend(AdcpVersionEnvelope): model_config = ConfigDict(extra='allow') total_spend: Annotated[float, Field(ge=0)] media_buy_count: Annotated[int, Field(ge=0)] | None = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var media_buy_count : int | Nonevar model_configvar total_spend : float
Inherited members
class StartingPosition (*args, **kwds)-
Expand source code
class StartingPosition(StrEnum): earliest = 'earliest' latest = 'latest'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var earliestvar latest
class Status22 (*args, **kwds)-
Expand source code
class Status22(StrEnum): completed = 'completed' failed = 'failed'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var completedvar failed
class SyncAccountsRequest (**data: Any)-
Expand source code
class SyncAccountsRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) idempotency_key: Annotated[ str, Field( description='Client-generated unique key for at-most-once execution. Natural per-account upsert keys handle resource-level dedup, but the envelope triggers onboarding webhooks, billing setup, and audit events — this key prevents those side effects from firing twice on retry. MUST be unique per (seller, request) pair. Use a fresh UUID v4 for each request.', max_length=255, min_length=16, pattern='^[A-Za-z0-9_.:-]{16,255}$', ), ] accounts: Annotated[ list[Accounts | Accounts1], Field( description='Per-account sync entries. Each entry uses one of two key shapes: the `account` field (AccountRef) for settings-update mode, or the flat `brand` + `operator` + `billing` trio for provisioning mode. An operator_identity settings update MUST carry the latest account revision.', max_length=1000, ), ] delete_missing: Annotated[ StrictBool | None, Field( description='When true, accounts previously synced by this agent but not included in this request will be deactivated. Scoped to the authenticated agent — does not affect accounts managed by other agents. Use with caution.' ), ] = False dry_run: Annotated[ StrictBool | None, Field( description='When true, preview what would change without applying. Returns what would be created/updated/deactivated.' ), ] = False push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( description='Webhook for async notifications when account status changes (e.g., pending_approval transitions to active).' ), ] = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe request message of a task in the pinned bundle's task registry.
A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is.
issubclass(model, AdcpRequest)is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.Each accessor returns the field's value, or
Nonewhen this tool's schema declares no such field. Only 49 of the 87 request schemas declare anaccountand only 43 anidempotency_key, so asking the request is what replacesgetattr(req, "account", None)againstAnyat the boundary.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpRequest
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var accounts : list[Accounts | Accounts1]var context : ContextObject | Nonevar delete_missing : bool | Nonevar dry_run : bool | Nonevar ext : ExtensionObject | Nonevar idempotency_key : strvar model_configvar push_notification_config : PushNotificationConfig | None
Inherited members
class SyncAccountsResponse1 (**data: Any)-
Expand source code
class SyncAccountsResponse1(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope): model_config = ConfigDict(extra='allow') dry_run: bool | None = None accounts: list[Account] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe response message of a task in the pinned bundle's task registry.
A consumer holding one can route on task state, pick up an async
task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var accounts : list[Account]var context : ContextObject | Nonevar dry_run : bool | Nonevar ext : ExtensionObject | Nonevar model_config
Inherited members
class SyncAccountsResponse2 (**data: Any)-
Expand source code
class SyncAccountsResponse2(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope): model_config = ConfigDict(extra='allow') errors: Annotated[list[error_1.Error], Field(min_length=1)] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe response message of a task in the pinned bundle's task registry.
A consumer holding one can route on task state, pick up an async
task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar errors : list[Error]var ext : ExtensionObject | Nonevar model_config
Inherited members
class SyncGovernanceRequest (**data: Any)-
Expand source code
class SyncGovernanceRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) idempotency_key: Annotated[ str, Field( description='Client-generated unique key for at-most-once execution. `account` gives resource-level dedup, but governance changes emit audit events and can trigger reapproval flows — this key prevents those side effects from firing twice on retry. MUST be unique per (seller, request) pair. Use a fresh UUID v4 for each request.', max_length=255, min_length=16, pattern='^[A-Za-z0-9_.:-]{16,255}$', ), ] accounts: Annotated[ list[Account], Field( description='Per-account governance agent configuration. Each entry pairs an account reference with the governance agents for that account.', max_length=100, min_length=1, ), ] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe request message of a task in the pinned bundle's task registry.
A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is.
issubclass(model, AdcpRequest)is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.Each accessor returns the field's value, or
Nonewhen this tool's schema declares no such field. Only 49 of the 87 request schemas declare anaccountand only 43 anidempotency_key, so asking the request is what replacesgetattr(req, "account", None)againstAnyat the boundary.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpRequest
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var accounts : list[Account]var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar idempotency_key : strvar model_config
Inherited members
class SyncGovernanceResponse (**data: Any)-
Expand source code
class SyncGovernanceResponse(AdcpResponse, ResponseArmDispatchMixin, AdcpVersionEnvelope, ProtocolEnvelope): """Constructible compatibility base for generated response arms.""" @classmethod def _response_arm_models(cls) -> tuple[type[SyncGovernanceResponse], ...]: return ( SyncGovernanceResponse1, SyncGovernanceResponse2, )Constructible compatibility base for generated response arms.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Subclasses
Class variables
var model_config
Inherited members
class SyncGovernanceResponse1 (**data: Any)-
Expand source code
class SyncGovernanceResponse1(SyncGovernanceResponse): model_config = ConfigDict( extra='allow', ) accounts: Annotated[list[Account], Field(description='Per-account sync results')] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneConstructible compatibility base for generated response arms.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- SyncGovernanceResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var accounts : list[Account]var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar model_config
Inherited members
class SyncGovernanceResponse2 (**data: Any)-
Expand source code
class SyncGovernanceResponse2(SyncGovernanceResponse): model_config = ConfigDict( extra='allow', ) errors: Annotated[ list[error.Error], Field( description='Operation-level errors (e.g., authentication failure, service unavailable)', min_length=1, ), ] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneConstructible compatibility base for generated response arms.
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- SyncGovernanceResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar errors : list[Error]var ext : ExtensionObject | Nonevar model_config
Inherited members
class UsageItem (**data: Any)-
Expand source code
class UsageItem(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) account: Annotated[ account_ref.AccountReference, Field(description='Account for this usage record.') ] media_buy_id: Annotated[ str | None, Field( description='Seller-assigned media buy identifier. Links this usage record to a specific media buy.' ), ] = None vendor_cost: Annotated[ StrictFloat, Field( description='Amount owed to the vendor for this record, denominated in currency.', ge=0.0, ), ] currency: Annotated[str, Field(description='ISO 4217 currency code.', pattern='^[A-Z]{3}$')] pricing_option_id: Annotated[ str | None, Field( description="Pricing option identifier from the vendor's discovery response (e.g., get_signals, list_content_standards). The vendor uses this to verify the correct rate was applied." ), ] = None impressions: Annotated[ SchemaInt | None, Field(description='Impressions delivered using this vendor service.', ge=0), ] = None media_spend: Annotated[ StrictFloat | None, Field( description='Media spend in currency for the period. Required when a percent_of_media pricing model was used, so the vendor can verify the applied rate.', ge=0.0, ), ] = None conversions: Annotated[ StrictFloat | None, Field( description='Number of attributed conversion events for the reporting period. Optional analytics context for revenue_share reconciliation.', ge=0.0, ), ] = None conversion_value: Annotated[ StrictFloat | None, Field( description='Total monetary value of attributed conversions for the reporting period, in currency. Optional analytics context for revenue_share reconciliation; it is not the billing basis.', ge=0.0, ), ] = None commissionable_value: Annotated[ StrictFloat | None, Field( description='Settled attributed value eligible for commission, in currency. Required when pricing_option_id selects a revenue_share option. The receiver verifies vendor_cost = round_currency(commissionable_value × the selected commission_rate).', ge=0.0, ), ] = None signal_agent_segment_id: Annotated[ str | None, Field(description='Signal identifier from get_signals. Required for signals agents.'), ] = None standards_id: Annotated[ str | None, Field( description='Content standards configuration identifier. Required for governance agents.' ), ] = None rights_id: Annotated[ str | None, Field( description='Rights grant identifier from acquire_rights. Required for brand/rights agents. Links usage records to specific rights grants for cap tracking, billing verification, and overage calculation.' ), ] = None creative_id: Annotated[ str | None, Field( description='Creative identifier from build_creative or list_creatives. Required for creative agents. Links usage records to specific creatives for billing verification.' ), ] = None build_variant_id: Annotated[ str | None, Field( description='Optional. When the reported creative_id was promoted from a specific build_creative variant leaf but the creative_id differs from the source build_variant_id, carry that source build_variant_id so billing reconciliation can link this usage record back to the exact produced leaf for audit (pricing_option_id alone is not unique across leaves). On the canonical path where creative_id is the build_variant_id, omit this field and use creative_id as the join key. Omit for creatives with no build-variant lineage.' ), ] = None property_list_id: Annotated[ str | None, Field( description='Property list identifier from list_property_lists. Required for property list agents. Links usage records to specific property lists for billing verification.' ), ] = None final: Annotated[ StrictBool | None, Field( description="Whether this usage record represents the reporter's final, billing-authoritative numbers for the reporting period. **Absent means unknown** — the reporter has not declared finality on this record. Set `true` only when the reporter has actually settled the numbers (e.g., 3PAS month-end close after SIVT scrubbing, conversion dedup, and view-through windows have closed; vendor file post-C7 for broadcast). Set `false` when pushing preliminary measurements (daily pacing pushes, intra-period progress) that are still settling. Receivers MUST NOT invoice on `final: false` records, and MUST NOT invoice on records where `final` is absent for buys whose `measurement_terms.billing_measurement` names this reporter as authoritative — request a final record first. Receivers MAY invoice on absent for buys with no `measurement_terms.billing_measurement` (3.0-style usage where the receiver treats reports as authoritative on receipt) and for non-media-buy variants (signals, governance, creative, brand — domains with no provisional state concept). When the same `(account, media_buy_id, reporting_period)` is later reported with `final: true`, that record supersedes any prior records for the period." ), ] = None finalized_at: Annotated[ AwareDatetime | None, Field( description="ISO 8601 timestamp at which the reporter considered these numbers final. Present only when `final: true`. Anchors any deadline declared in the buy's `measurement_terms.billing_measurement.finalization_deadline_hours`." ), ] = None measurement_window: Annotated[ str | None, Field( description="Which measurement window this record represents, referencing a window_id from the product's reporting_capabilities.measurement_windows or from `measurement_terms.billing_measurement.measurement_window`. Examples: 'c7' for broadcast TV, 'post_sivt' for digital post-IVT, 'downloads_30d' for podcast. When absent, the record is not windowed (standard digital reporting). When the buy's `measurement_terms.billing_measurement.measurement_window` is set, reporters SHOULD include `measurement_window` so the receiver can reconcile against the correct stage.", examples=['live', 'c3', 'c7', 'post_ivt', 'post_sivt', 'downloads_30d'], max_length=50, ), ] = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2var build_variant_id : str | Nonevar commissionable_value : float | Nonevar conversion_value : float | Nonevar conversions : float | Nonevar creative_id : str | Nonevar currency : strvar final : bool | Nonevar finalized_at : pydantic.types.AwareDatetime | Nonevar impressions : int | Nonevar measurement_window : str | Nonevar media_buy_id : str | Nonevar media_spend : float | Nonevar model_configvar pricing_option_id : str | Nonevar property_list_id : str | Nonevar rights_id : str | Nonevar signal_agent_segment_id : str | Nonevar standards_id : str | Nonevar vendor_cost : float
Inherited members