Module adcp.types.domains.compliance
Types the AdCP compliance 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.compliance 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.compliance.<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.compliance.comply_test_controller_requestadcp.types.domains.compliance.comply_test_controller_responseadcp.types.domains.compliance.get_creative_features_completionadcp.types.domains.compliance.task_completion_data
Classes
class Account (**data: Any)-
Expand source code
class Account(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) sandbox: Annotated[ Literal[True], Field( description='MUST be true. The seller MUST verify the targeted account is sandbox by looking up the persisted account record, not by trusting this field. A request asserting sandbox: false schema-rejects before reaching the seller — defense-in-depth on top of the per-request gate.' ), ]Base model for AdCP types with spec-compliant 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 model_configvar sandbox : Literal[True]
Inherited members
class AdvanceTo (*args, **kwds)-
Expand source code
class AdvanceTo(StrEnum): within_grace = 'within_grace' past_grace = 'past_grace'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var past_gracevar within_grace
class Arm (*args, **kwds)-
Expand source code
class Arm(StrEnum): submitted = 'submitted' completed = 'completed' input_required = 'input-required' rejected = 'rejected'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var completedvar input_requiredvar rejectedvar submitted
class AttestationMode (*args, **kwds)-
Expand source code
class AttestationMode(StrEnum): raw = 'raw' digest = 'digest'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var digestvar raw
class ComplyResponseArm (*args, **kwds)-
Expand source code
class ComplyResponseArm(StrEnum): submitted = 'submitted' completed = 'completed' input_required = 'input-required' rejected = 'rejected'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var completedvar input_requiredvar rejectedvar submitted
class ComplyTestControllerRequest (**data: Any)-
Expand source code
class ComplyTestControllerRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) scenario: Annotated[ str, Field( description="Test scenario to execute. 'list_scenarios' discovers supported scenarios. 'force_*' and 'simulate_*' trigger state transitions. 'reporting_core_lifecycle_probe' installs a caller/account-scoped Core fixture whose first elapsed obligation is visible before any report, advances its virtual clock into delayed or action_required, and can publish deterministic zero-row or non-empty revisions, restate a provisional revision, restate one the caller already received, or cross the consumer-status deadline and consumer-mismatch escalation boundaries, without waiting for wall-clock boundaries. Other scenarios provide deterministic sandbox probes for their documented lifecycle checks. Runners and sellers MUST accept unknown scenario strings - new scenarios may be added in additive releases." ), ] params: Annotated[ Params | None, Field( description='Scenario-specific parameters. Required for all scenarios except list_scenarios.' ), ] = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None account: Annotated[ Account | None, Field( description="Sandbox account assertion. The runner MUST set sandbox: true on every comply_test_controller request. The seller MUST refuse the request (returning a structured error) if the targeted account is not a sandbox account in the seller's persisted records. This field is a caller-side declaration of intent — it does not grant sandbox status; sellers verify against their own account state. The (Sandbox) verification tier is defined by this gate: real production endpoints accept sandbox-flagged traffic and process it without real-world side effects, no separate test-mode endpoint required. See spec issue #3755 and the (Sandbox) framing in #4379." ), ] = 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 : Account | Nonevar context : ContextObject | Nonevar ext : ExtensionObject | Nonevar model_configvar params : Params | Nonevar scenario : str
Inherited members
class ComplyTestControllerResponse (**data: Any)-
Expand source code
class ComplyTestControllerResponse(AdcpResponse, ResponseArmDispatchMixin, AdcpVersionEnvelope, ProtocolEnvelope): """Constructible compatibility base for generated response arms.""" @classmethod def _response_arm_models(cls) -> tuple[type[ComplyTestControllerResponse], ...]: return ( ComplyTestControllerResponse1, ComplyTestControllerResponse2, ComplyTestControllerResponse3, ComplyTestControllerResponse4, ComplyTestControllerResponse5, ComplyTestControllerResponse6, ComplyTestControllerResponse7, ComplyTestControllerResponse8, )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
- ComplyTestControllerResponse1
- ComplyTestControllerResponse2
- ComplyTestControllerResponse3
- ComplyTestControllerResponse4
- ComplyTestControllerResponse5
- ComplyTestControllerResponse6
- ComplyTestControllerResponse7
- ComplyTestControllerResponse8
Class variables
var model_config
Inherited members
class ComplyTestControllerResponse1 (**data: Any)-
Expand source code
class ComplyTestControllerResponse1(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[True] scenarios: Annotated[ list[str], Field( description='Scenarios this seller has implemented. Runners and sellers MUST accept unknown scenario strings (open-for-extension) — new scenarios may be added in additive releases. Adopters who advertise `catalog_item_availability_probe` support deterministic cross-principal reference, eligibility-gate, expiry-clock, and catalog-generation tests for the catalog availability storyboard. Adopters who advertise `compact_product_lifecycle_probe` support deterministic synchronous list/request/finalize/decline/accept/control/readback behavior for a prepared product and strict post-deadline expiry of a committed proposal. Adopters who advertise `compact_direct_buy_lifecycle_probe` support deterministic synchronous list/buy/control/readback behavior for a prepared product. Adopters who advertise `reporting_core_lifecycle_probe` support deterministic obligation-before-report, clock-health, zero-row reporting, provisional-restatement, and post-received restatement-grace tests without wall-clock waits. `reliable_reporting_core_integrity_probe`, `reliable_reporting_managed_delivery_probe`, and `reliable_reporting_reconciled_billing_probe` seed the source-calendar/checkpoint, managed-resource, and receipt/adjustment workflows used by the Reliable Reporting tier storyboards. Adopters who advertise `force_creative_purge` opt in to deterministic creative purge coverage for account-level lifecycle webhooks. Adopters who advertise `force_media_buy_purge` opt in to deterministic deletion-independent idempotency replay coverage. Adopters who advertise `seed_measurement_catalog` opt in to deterministic measurement-catalog fixtures used by vendor_metric precondition storyboards. Adopters who advertise `query_upstream_traffic` opt in to the upstream-traffic conformance contract; storyboards that declare `check: upstream_traffic` grade not_applicable against adopters who do not advertise it. Adopters who advertise `query_provenance_audit_observations` opt in to sandbox-only audit-observation assertions for accepted creatives. Adopters who advertise `force_upstream_unavailable` opt in to stale-cache conformance testing via the `stale_response_advisory` storyboard.' ), ] 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar model_configvar scenarios : list[str]var success : Literal[True]
Inherited members
class ComplyTestControllerResponse2 (**data: Any)-
Expand source code
class ComplyTestControllerResponse2(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[True] previous_state: Annotated[str, Field(description='State before this transition')] current_state: Annotated[str, Field(description='State after this transition')] message: Annotated[ str | None, Field(description='Human-readable description of the transition') ] = None 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar current_state : strvar ext : ExtensionObject | Nonevar message : str | Nonevar model_configvar previous_state : strvar success : Literal[True]
Inherited members
class ComplyTestControllerResponse3 (**data: Any)-
Expand source code
class ComplyTestControllerResponse3(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[True] simulated: Annotated[ dict[str, Any], Field(description='Values injected or applied by this call. Shape depends on scenario.'), ] cumulative: Annotated[ dict[str, Any] | None, Field(description='Running totals across all simulation calls (simulate_delivery only)'), ] = None message: str | None = None 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar cumulative : dict[str, typing.Any] | Nonevar ext : ExtensionObject | Nonevar message : str | Nonevar model_configvar simulated : dict[str, typing.Any]var success : Literal[True]
Inherited members
class ComplyTestControllerResponse4 (**data: Any)-
Expand source code
class ComplyTestControllerResponse4(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[True] forced: Annotated[ Forced, Field( description='Echo of the registered directive. The next matching operation call from this sandbox account will return the named arm.' ), ] message: Annotated[str | None, Field(description='Human-readable acknowledgement.')] = None 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar forced : Forcedvar message : str | Nonevar model_configvar success : Literal[True]
Inherited members
class ComplyTestControllerResponse5 (**data: Any)-
Expand source code
class ComplyTestControllerResponse5(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[True] message: Annotated[str | None, Field(description='Human-readable acknowledgement.')] = None 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar message : str | Nonevar model_configvar success : Literal[True]
Inherited members
class ComplyTestControllerResponse6 (**data: Any)-
Expand source code
class ComplyTestControllerResponse6(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[True] creative_id: Annotated[ str, Field(description='Creative ID whose audit observations were queried.') ] audit_observations: Annotated[ list[audit_observation.CreativeAuditObservation], Field(description='Audit observations recorded for the creative in the sandbox session.'), ] 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var audit_observations : list[CreativeAuditObservation]var context : ContextObject | Nonevar creative_id : strvar ext : ExtensionObject | Nonevar model_configvar success : Literal[True]
Inherited members
class ComplyTestControllerResponse7 (**data: Any)-
Expand source code
class ComplyTestControllerResponse7(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[True] recorded_calls: Annotated[ list[RecordedCalls], Field( description="Outbound HTTP calls caused by the requesting principal in the requested window, ordered by `timestamp` ascending. Cross-caller calls MUST NOT appear here. Each item declares its `attestation_mode`: `raw` items carry the full `payload`; `digest` items carry `payload_digest_sha256` + `payload_length` + optional `identifier_match_proofs[]` instead, for adopters who can't return raw payloads under their privacy/data-residency policy." ), ] total_count: Annotated[ SchemaInt, Field( description='Total calls in the requested window before any pagination — `recorded_calls.length` may be smaller when `params.limit` truncated the response.', ge=0, ), ] truncated: Annotated[ StrictBool | None, Field( description='True when `total_count > recorded_calls.length`. Runners MAY raise the `limit` and re-query, but storyboards SHOULD declare assertions that fit within the default 100-call window — a truncated response is a signal that the storyboard step is causing more upstream activity than expected.' ), ] = None since_timestamp: Annotated[ AwareDatetime, Field( description="Echo of the `since_timestamp` the runner requested (or the session-start timestamp the adopter substituted when the runner omitted it). Informational — the runner SHOULD use its own clock-bracket of when it issued the AdCP step request, not this echo, when attributing recorded_calls to a specific step. The controller is part of the adopter's claimed conformance; the echo is not adversarially trustworthy." ), ] 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar model_configvar recorded_calls : list[RecordedCalls1 | RecordedCalls2]var since_timestamp : pydantic.types.AwareDatetimevar success : Literal[True]var total_count : intvar truncated : bool | None
Inherited members
class ComplyTestControllerResponse8 (**data: Any)-
Expand source code
class ComplyTestControllerResponse8(ComplyTestControllerResponse): model_config = ConfigDict( extra='allow', ) success: Literal[False] error: Annotated[ Error, Field( description='Structured error code. `JCS_NON_FINITE_NUMBER` is reserved for digest-mode upstream_traffic responses that cannot be RFC 8785/JCS-canonicalized because the parsed JSON-like value tree contains a non-finite numeric value (`NaN`, `+Infinity`, or `-Infinity`); controllers MUST NOT coerce those values during digest computation, and runners grade that validation `not_applicable`, not failed.' ), ] error_detail: Annotated[ str | None, Field(description='Human-readable explanation of the failure') ] = None current_state: Annotated[ str | None, Field(description='Current state of the entity, or null if not found') ] = None 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
- ComplyTestControllerResponse
- AdcpResponse
- adcp.types.base._AdcpMessage
- ResponseArmDispatchMixin
- AdcpVersionEnvelope
- ProtocolEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar current_state : str | Nonevar error : Errorvar error_detail : str | Nonevar ext : ExtensionObject | Nonevar model_configvar success : Literal[False]
Inherited members
class Error (*args, **kwds)-
Expand source code
class Error(StrEnum): INVALID_TRANSITION = 'INVALID_TRANSITION' INVALID_STATE = 'INVALID_STATE' NOT_FOUND = 'NOT_FOUND' UNKNOWN_SCENARIO = 'UNKNOWN_SCENARIO' INVALID_PARAMS = 'INVALID_PARAMS' FORBIDDEN = 'FORBIDDEN' JCS_NON_FINITE_NUMBER = 'JCS_NON_FINITE_NUMBER' INTERNAL_ERROR = 'INTERNAL_ERROR'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var FORBIDDENvar INTERNAL_ERRORvar INVALID_PARAMSvar INVALID_STATEvar INVALID_TRANSITIONvar JCS_NON_FINITE_NUMBERvar NOT_FOUNDvar UNKNOWN_SCENARIO
class Forced (**data: Any)-
Expand source code
class Forced(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) arm: Annotated[ ComplyResponseArm, Field(description='ComplyResponseArm the seller will emit on the next forced operation response.') ] task_id: Annotated[ str | None, Field( description="Echo of the registered task_id. Present only when arm is 'submitted' (the arm that emits a task envelope).", max_length=128, ), ] = None evaluation_id: Annotated[ str | None, Field( description='Echo of the provider evaluation identity registered by force_get_creative_features_arm.', max_length=255, min_length=1, ), ] = None reason: Annotated[ str | None, Field( description="Echo of the deterministic buyer-facing rejection reason. Required when arm is 'rejected'.", max_length=2000, min_length=1, ), ] = None suggestions: Annotated[ list[Suggestion] | None, Field( description='Echo of the optional deterministic alternatives registered for a rejected get_products response.', max_length=20, min_length=1, ), ] = 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 arm : ComplyResponseArmvar evaluation_id : str | Nonevar model_configvar reason : str | Nonevar suggestions : list[Suggestion] | Nonevar task_id : str | None
Inherited members
class GetCreativeFeaturesComplianceCompletion (**data: Any)-
Expand source code
class GetCreativeFeaturesComplianceCompletion(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) status: Literal['completed'] = 'completed' evaluation_id: Annotated[str, Field(min_length=1)] results: list[creative_feature_result.CreativeFeatureResult] pricing_option_id: str | None = None vendor_cost: Annotated[StrictFloat | None, Field(ge=0.0)] = None currency: Annotated[str | None, Field(pattern='^[A-Z]{3}$')] = None consumption: creative_consumption.CreativeConsumption | 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
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var consumption : CreativeConsumption | Nonevar currency : str | Nonevar evaluation_id : strvar model_configvar pricing_option_id : str | Nonevar results : list[CreativeFeatureResult]var status : Literal['completed']var vendor_cost : float | None
Inherited members
class IdentifierMatchProof (**data: Any)-
Expand source code
class IdentifierMatchProof(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) identifier_value_sha256: Annotated[ str, Field( description='Echo of one digest from `params.identifier_value_digests` so the runner can pair this proof with the identifier it queried.', pattern='^[a-f0-9]{64}$', ), ] found: Annotated[ StrictBool, Field( description='True if any string token in the recorded payload hashes to the queried digest. False otherwise.' ), ]Base model for AdCP types with spec-compliant 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 found : boolvar identifier_value_sha256 : strvar model_config
Inherited members
class Kind (*args, **kwds)-
Expand source code
class Kind(StrEnum): cumulative = 'cumulative' period = 'period' rolling = 'rolling'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var cumulativevar periodvar rolling
class Method (*args, **kwds)-
Expand source code
class Method(StrEnum): GET = 'GET' POST = 'POST' PUT = 'PUT' PATCH = 'PATCH' DELETE = 'DELETE' HEAD = 'HEAD' OPTIONS = 'OPTIONS'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var DELETEvar GETvar HEADvar OPTIONSvar PATCHvar POSTvar PUT
class Metric (**data: Any)-
Expand source code
class Metric(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) metric_id: vendor_metric_id.VendorMetricIdBase model for AdCP types with spec-compliant 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 metric_id : VendorMetricIdvar model_config
Inherited members
class NotYetMeasurableVendorMetric (**data: Any)-
Expand source code
class NotYetMeasurableVendorMetric(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) vendor: brand_ref.BrandReference metric_id: vendor_metric_id.VendorMetricId qualifier: Annotated[ committed_metric.Qualifier | None, Field( description='Qualifier for the exact committed vendor-metric row whose measurement is deferred.' ), ] = 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
Subclasses
Class variables
var metric_id : VendorMetricIdvar model_configvar qualifier : Qualifier | Nonevar vendor : BrandReference
Inherited members
class NotYetMeasurableVendorMetricsByPackageItem (**data: Any)-
Expand source code
class NotYetMeasurableVendorMetricsByPackageItem(NotYetMeasurableVendorMetric): passBase model for AdCP types with spec-compliant 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
- NotYetMeasurableVendorMetric
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var model_config
Inherited members
class Operation (*args, **kwds)-
Expand source code
class Operation(StrEnum): seed_inaccessible_item = 'seed_inaccessible_item' query_eligibility = 'query_eligibility' advance_time = 'advance_time' recreate_catalog = 'recreate_catalog' prepare = 'prepare' expire_proposal = 'expire_proposal' publish_zero_row = 'publish_zero_row' publish_nonempty = 'publish_nonempty' restate_snapshot = 'restate_snapshot' restate_after_received = 'restate_after_received' omit_obligation = 'omit_obligation' advance_past_status_deadline = 'advance_past_status_deadline' advance_past_escalation = 'advance_past_escalation' publish_official_adjustment = 'publish_official_adjustment' probe_scheduler_dst = 'probe_scheduler_dst' suppress_readiness = 'suppress_readiness' advance_within_retention = 'advance_within_retention' revoke_access = 'revoke_access' publish_adjustment = 'publish_adjustment'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var advance_past_escalationvar advance_past_status_deadlinevar advance_timevar advance_within_retentionvar expire_proposalvar omit_obligationvar preparevar probe_scheduler_dstvar publish_adjustmentvar publish_nonemptyvar publish_official_adjustmentvar publish_zero_rowvar query_eligibilityvar recreate_catalogvar restate_after_receivedvar restate_snapshotvar revoke_accessvar seed_inaccessible_itemvar suppress_readiness
class Params (**data: Any)-
Expand source code
class Params(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) creative_id: Annotated[ str | None, Field( description='Creative to transition (force_creative_status) or seed (seed_creative).' ), ] = None account_id: Annotated[ str | None, Field( description='Account to transition, simulate, or seed. Used by force_account_status, simulate_budget_spend, and seed_account.' ), ] = None media_buy_id: Annotated[ str | None, Field( description='Media buy to transition or purge (force_media_buy_status, force_media_buy_purge), simulate (simulate_delivery, simulate_budget_spend), or seed (seed_media_buy).' ), ] = None session_id: Annotated[ str | None, Field(description='Session to transition. Used by force_session_status.') ] = None product_id: Annotated[ str | None, Field( description='Product to seed or prepare for deterministic compact lifecycle testing. Used by seed_product, seed_pricing_option, compact_product_lifecycle_probe prepare, and compact_direct_buy_lifecycle_probe prepare.' ), ] = None proposal_id: Annotated[ str | None, Field( description='Committed proposal whose hold the compact_product_lifecycle_probe expires.', min_length=1, ), ] = None pricing_option_id: Annotated[ str | None, Field( description='Pricing option to seed, scoped to a product. Used by seed_pricing_option.' ), ] = None plan_id: Annotated[str | None, Field(description='Plan to seed. Used by seed_plan.')] = None rights_id: Annotated[ str | None, Field(description='Rights grant to seed. Used by seed_rights_grant.') ] = None fixture: Annotated[ dict[str, Any] | None, Field( description='Arbitrary fixture payload carried by seed_* scenarios. Shape matches the domain object the seed scenario creates (account, product, creative, plan, media buy, pricing option, rights grant). Seller MAY reject malformed fixtures with INVALID_PARAMS. Kept permissive so storyboard authors can declare the minimum shape each test needs without the spec locking down every field.' ), ] = None operation: Annotated[ Operation | None, Field( description="Scenario-specific probe operation. catalog_item_availability_probe uses seed_inaccessible_item, query_eligibility, advance_time, and recreate_catalog. compact_product_lifecycle_probe uses prepare to make one seeded product's compact proposal, acceptance, operational-control, and MediaBuy readback path deterministic and expire_proposal to advance strictly beyond a committed proposal's stored expires_at and process the hold lapse. compact_direct_buy_lifecycle_probe uses prepare to make one seeded product's list, direct-purchase, operational-control, and readback path deterministic. reporting_core_lifecycle_probe uses prepare, advance_time, publish_zero_row, publish_nonempty, restate_snapshot, restate_after_received, omit_obligation, advance_past_status_deadline, and advance_past_escalation to exercise obligation availability, health deadlines, explicit reporting, provisional restatement, stale-received grace, buyer-side missing-obligation detection, counted consumer-status silence, and consumer-mismatch escalation. advance_past_status_deadline moves the clock strictly past expected_at plus the advertised automated_recovery_window_seconds without recording any consumer status, so obligation_counts.consumer_status_pending is gradable; advance_past_escalation moves it strictly past the open CONSUMER_STATUS_MISMATCH issue opened_at plus the advertised consumer_mismatch_escalation_seconds and returns both that boundary and any still-future stale_received_grace_deadline, so the escalation precedence rule is gradable. restate_snapshot publishes a new snapshot revision that immediately supersedes the current snapshot for the same logical slice and is invalid when the current revision is official. restate_after_received does the same restatement but only against the revision named in received_reporting_revision_id, so the stale-received grace projection can be graded live; it returns the grace deadline and advance_to positions the virtual clock inside or past it. Reliable Reporting tier probes use prepare plus publish_official_adjustment, probe_scheduler_dst, suppress_readiness, advance_within_retention, revoke_access, or publish_adjustment to seed deterministic Core-integrity, Managed Delivery, and Reconciled Billing lifecycle evidence." ), ] = None target_health: Annotated[ TargetHealth | None, Field( description='Clock-derived health boundary selected by reporting_core_lifecycle_probe advance_time. The controller chooses the corresponding deterministic target time; callers do not supply timestamps.' ), ] = None received_reporting_revision_id: Annotated[ str | None, Field( description="Revision the caller currently reports as received, required by reporting_core_lifecycle_probe restate_after_received. The seller MUST reject the operation unless this names the caller's current required revision for the fixture obligation, and a seller advertising consumer_status_task MUST additionally require a current received consumer status from this caller naming it. This binds the restatement to a real prior read instead of restating into a vacuum.", max_length=255, min_length=1, pattern='^[A-Za-z0-9_.:-]{1,255}$', ), ] = None advance_to: Annotated[ AdvanceTo | None, Field( description='Where reporting_core_lifecycle_probe restate_after_received leaves the virtual clock relative to the returned stale_received_grace_deadline. within_grace grades the delayed projection; past_grace grades the escalation to action_required. Repeating the operation is convergent: it reuses the committed restatement and only moves the clock.' ), ] = AdvanceTo.within_grace catalog_id: Annotated[ str | None, Field( description='Catalog operated on by catalog_item_availability_probe.', max_length=255, min_length=1, ), ] = None catalog_generation: Annotated[ str | None, Field( description='Catalog incarnation operated on by catalog_item_availability_probe.', max_length=255, min_length=1, ), ] = None item_id: Annotated[ str | None, Field( description='Catalog item operated on by catalog_item_availability_probe.', max_length=255, min_length=1, ), ] = None target_time: Annotated[ AwareDatetime | None, Field( description='Deterministic sandbox clock target used by catalog_item_availability_probe advance_time.' ), ] = None status: Annotated[ str | None, Field( description="Target status for the resource. Type depends on scenario: creative-status for force_creative_status, account-status for force_account_status, media-buy-status for force_media_buy_status. For force_session_status, must be 'complete' or 'terminated'." ), ] = None rejection_reason: Annotated[ str | None, Field( description='Reason for rejection. Used by force_creative_status and force_media_buy_status when status = rejected.' ), ] = None purge_kind: Annotated[ PurgeKind | None, Field( description='Purge mode for force_creative_purge. soft retains a list_creatives tombstone; hard removes the creative entirely.' ), ] = None reason_code: Annotated[ creative_event_reason_code.CreativeEventReasonCode | None, Field( description='Creative lifecycle reason code for force_creative_status and force_creative_purge.' ), ] = None reason_detail: Annotated[ str | None, Field( description='Human-readable detail for force_creative_status and force_creative_purge.' ), ] = None termination_reason: Annotated[ str | None, Field( description='Reason for termination (e.g., session_timeout, host_terminated, policy_violation). Used by force_session_status when status = terminated.' ), ] = None impressions: Annotated[ SchemaInt | None, Field(description='Impressions to simulate. Used by simulate_delivery.', ge=0), ] = None clicks: Annotated[ SchemaInt | None, Field(description='Clicks to simulate. Used by simulate_delivery.', ge=0) ] = None plays: Annotated[ SchemaInt | None, Field( description='Raw DOOH or broadcast plays to add to delivery. Used by simulate_delivery for single-package buys; sellers MUST surface the cumulative value at totals.plays and by_package[0].plays in the next get_media_buy_delivery response. Multi-package simulations require a future package-scoped form and MUST reject this media-buy-scoped field.', ge=0, ), ] = None dooh_metrics: Annotated[ delivery_metrics.DoohMetrics | None, Field( description='DOOH delivery detail to inject. Used by simulate_delivery for single-package buys; the latest injected block replaces the previous simulated DOOH detail and MUST surface at totals.dooh_metrics and by_package[0].dooh_metrics. Multi-package simulations require a future package-scoped form and MUST reject this media-buy-scoped field.' ), ] = None conversions: Annotated[ SchemaInt | None, Field(description='Conversions to simulate. Used by simulate_delivery.', ge=0), ] = None delivery_date: Annotated[ date | None, Field( description="Calendar date, in the product's reporting_capabilities.timezone, attributable to this simulated delivery batch. Used by simulate_delivery to seed deterministic date-range tests. When get_media_buy_delivery supplies start_date or end_date, dated batches are included when delivery_date is greater than or equal to start_date and strictly less than end_date. Omit to preserve cumulative, unfiltered simulation behavior." ), ] = None conversion_value: Annotated[ StrictFloat | None, Field( description='Total attributed conversion value to simulate in the delivery reporting currency. Used by simulate_delivery.', ge=0.0, ), ] = None commissionable_value: Annotated[ StrictFloat | None, Field( description='Settled attributed value eligible for revenue-share commission to simulate in the delivery reporting currency. Used by simulate_delivery.', ge=0.0, ), ] = None reported_spend: Annotated[ ReportedSpend | None, Field( description='Spend as reported in delivery data. Does not affect budget. Used by simulate_delivery.' ), ] = None reach: Annotated[ StrictFloat | None, Field( description="Unique reach count to inject into the simulated delivery row. Used by simulate_delivery. The unit of measurement matches the reach_unit declared on the media buy's optimization goal. When supplied, sellers MUST surface this value at `totals.reach` in the next get_media_buy_delivery response.", ge=0.0, ), ] = None frequency: Annotated[ StrictFloat | None, Field( description='Average frequency per reach unit to inject. Used by simulate_delivery. When supplied, sellers MUST surface this value at `totals.frequency`, including frequency-only delivery. The measurement window for this frequency value is declared in `reach_window` when also present.', ge=0.0, ), ] = None reach_unit: Annotated[ reach_unit_1.ReachUnit | None, Field( description='Unit for an injected reach or frequency value. Used by simulate_delivery. When supplied with reach or frequency, sellers MUST surface it on the corresponding delivery row.' ), ] = None reach_window: Annotated[ ReachWindow | None, Field( description='Measurement window semantics to attach to the simulated reach and frequency values. Used by simulate_delivery. When present, sellers MUST populate `reach_window` on the delivery row so buyers can determine the window semantics (cumulative vs. period vs. rolling). Omitting this param produces a row with no `reach_window` — valid per schema but sum-unsafe. Mirrors the `reach_window` shape in delivery-metrics.json.' ), ] = None viewability: Annotated[ delivery_metrics.Viewability | None, Field( description='Viewability metrics to inject into simulated delivery. Uses the canonical delivery viewability shape, including viewed-seconds distributions. This media-buy-scoped form is valid only for a single-package buy, where the reference seller surfaces the same values at package and media-buy totals grain.' ), ] = None vendor_metric_values: Annotated[ list[vendor_metric_value.VendorMetricValue] | None, Field( description="Vendor-defined metric values to inject into the next delivery report. Used by simulate_delivery. The reference seller reconciles these rows against each package's seller-stamped committed_metrics contract." ), ] = None vendor_metric_values_by_package: Annotated[ dict[str, list[vendor_metric_value.VendorMetricValue]] | None, Field( description='Package-scoped vendor-defined values to inject, keyed by package_id. Used by simulate_delivery for multi-package buys. Sellers MUST use this form whenever more than one package could carry the same vendor/metric_id key; the legacy media-buy-scoped vendor_metric_values form is unambiguous only for a single-package buy.' ), ] = None not_yet_measurable_vendor_metrics: Annotated[ list[NotYetMeasurableVendorMetric] | None, Field( description='Committed vendor metrics that are not yet measurable for the simulated measurement window. Used by simulate_delivery to prove that a future metric is omitted from missing_metrics until its measurement window matures.' ), ] = None not_yet_measurable_vendor_metrics_by_package: Annotated[ dict[str, list[NotYetMeasurableVendorMetricsByPackageItem]] | None, Field( description="Package-scoped committed vendor metrics that are not yet measurable for the simulated window, keyed by package_id. Used by simulate_delivery for multi-package buys so a deferral on one package never suppresses another package's overdue gap." ), ] = None spend_percentage: Annotated[ StrictFloat | None, Field( description='Spend to this percentage of budget (0–100). Used by simulate_budget_spend.', ge=0.0, le=100.0, ), ] = None arm: Annotated[ Arm | None, Field( description="Response arm for the next forced operation call. Used by force_create_media_buy_arm, force_get_products_arm, force_get_signals_arm, and force_get_creative_features_arm. 'submitted' is supported for all four operations; get_creative_features also supports 'completed' with a deterministic result; create_media_buy also supports 'input-required'; get_products also supports 'rejected'. Async completion after a submitted task is covered by force_task_completion; 'working' is an out-of-band progress signal, not an initial response arm." ), ] = None task_id: Annotated[ str | None, Field( description="Deterministic task handle the seller MUST emit verbatim on the next forced operation response when arm is 'submitted'. The seller MUST accept this exact value on subsequent tasks/get or get_task_status calls within the same authenticated sandbox account + principal pair and MUST return REFERENCE_NOT_FOUND for the same task_id under any other account or principal. Sandbox task_ids are caller-opaque strings - the seller's production task-id format rules do not apply.", max_length=128, ), ] = None evaluation_id: Annotated[ str | None, Field( description='Deterministic provider evaluation identity the seller MUST emit on the next forced get_creative_features submitted acknowledgement and preserve on its terminal completion result.', max_length=255, min_length=1, ), ] = None message: Annotated[ str | None, Field( description='Optional human-readable explanation surfaced on the next forced operation response. Used by force_create_media_buy_arm, force_get_products_arm, force_get_signals_arm, and force_get_creative_features_arm for the submitted arm. Plain text only.', max_length=2000, ), ] = None reason: Annotated[ str | None, Field( description="Deterministic buyer-facing reason the seller MUST emit on the next get_products response when force_get_products_arm uses arm 'rejected'. Plain text only; MUST NOT expose confidential internal rules, inventory identifiers, credentials, or stack traces.", max_length=2000, min_length=1, ), ] = None suggestions: Annotated[ list[Suggestion] | None, Field( description="Optional deterministic alternatives the seller MUST emit on the next get_products rejection. Used only by force_get_products_arm with arm 'rejected'.", max_length=20, min_length=1, ), ] = None format_id: Annotated[ str | None, Field( deprecated=True, description='**DEPRECATED 3.x compatibility fixture.** Legacy named-format ID to seed for seed_creative_format scenarios. The seller MUST expose it through the deprecated list_creative_formats projection for the duration of the compliance session. Canonical 3.2 scenarios seed creative.supported_formats capabilities instead.', ), ] = None vendor: Annotated[ brand_ref.BrandReference | None, Field( description="Measurement vendor whose catalog is being seeded. Used by seed_measurement_catalog. The seller MUST treat `metrics[]` as this vendor's `get_adcp_capabilities.measurement.metrics[]` snapshot for the duration of the compliance session." ), ] = None metrics: Annotated[ list[Metric] | None, Field( description='Measurement catalog entries to seed for the vendor. Used by seed_measurement_catalog. Shape mirrors `get_adcp_capabilities.measurement.metrics[]`; each metric_id is unique within the seeded vendor catalog.', min_length=1, ), ] = None tool: Annotated[ str | None, Field( description="Tool name whose upstream dependency to affect. Used by force_upstream_unavailable. The seller marks the named upstream as unreachable for subsequent calls to this tool within the compliance session. Sellers MAY accept a wildcard ('*') to affect all tools." ), ] = None upstream_name: Annotated[ str | None, Field( description="Human-readable identifier for the upstream dependency to force unavailable (e.g., 'inventory-service', 'creative-agent'). Used by force_upstream_unavailable. When omitted, the seller marks its default upstream for the specified tool as unavailable. Sellers MUST include the same name in STALE_RESPONSE error.details.upstream.name on the affected response." ), ] = None cache_age_seconds: Annotated[ SchemaInt | None, Field( description='Deterministic age of the stale cache entry used by force_upstream_unavailable. When supplied, the seller MUST emit this exact value in the matching STALE_RESPONSE error.details.cache_age_seconds on the next affected response. This lets the conformance runner bind the advisory code and its required detail fields to the same errors[] entry without assuming array order.', ge=0, ), ] = None result: Annotated[ task_completion_data.ComplianceTaskCompletionData | None, Field( description="Deterministic result payload. force_get_creative_features_arm uses it when arm is completed and returns it on the next matching operation call. force_task_completion records it against an existing task and supports the bounded get_products, get_signals, create_media_buy, and get_creative_features completion union; polling and production SDKs resolve all task results through the originating task's manifest response mapping instead of embedding a global result union. The seller MUST preserve caller-supplied fields. Sellers MUST emit INVALID_PARAMS when the payload does not match the required response branch and MAY reject payloads exceeding 256 KB." ), ] = 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_id : str | Nonevar advance_to : AdvanceTo | Nonevar arm : Arm | Nonevar cache_age_seconds : int | Nonevar catalog_generation : str | Nonevar catalog_id : str | Nonevar clicks : int | Nonevar commissionable_value : float | Nonevar conversion_value : float | Nonevar conversions : int | Nonevar creative_id : str | Nonevar delivery_date : datetime.date | Nonevar dooh_metrics : DoohMetrics | Nonevar evaluation_id : str | Nonevar fixture : dict[str, typing.Any] | Nonevar format_id : str | Nonevar frequency : float | Nonevar impressions : int | Nonevar item_id : str | Nonevar media_buy_id : str | Nonevar message : str | Nonevar metrics : list[Metric] | Nonevar model_configvar not_yet_measurable_vendor_metrics : list[NotYetMeasurableVendorMetric] | Nonevar not_yet_measurable_vendor_metrics_by_package : dict[str, list[NotYetMeasurableVendorMetricsByPackageItem]] | Nonevar operation : Operation | Nonevar plan_id : str | Nonevar plays : int | Nonevar pricing_option_id : str | Nonevar product_id : str | Nonevar proposal_id : str | Nonevar purge_kind : PurgeKind | Nonevar reach : float | Nonevar reach_unit : ReachUnit | Nonevar reach_window : ReachWindow | Nonevar reason : str | Nonevar reason_code : CreativeEventReasonCode | Nonevar reason_detail : str | Nonevar received_reporting_revision_id : str | Nonevar rejection_reason : str | Nonevar reported_spend : ReportedSpend | Nonevar result : GetProductsResponse | GetSignalsResponse | CreateMediaBuyResponse1 | GetCreativeFeaturesComplianceCompletion | Nonevar rights_id : str | Nonevar session_id : str | Nonevar spend_percentage : float | Nonevar status : str | Nonevar suggestions : list[Suggestion] | Nonevar target_health : TargetHealth | Nonevar target_time : pydantic.types.AwareDatetime | Nonevar task_id : str | Nonevar termination_reason : str | Nonevar tool : str | Nonevar upstream_name : str | Nonevar vendor : BrandReference | Nonevar vendor_metric_values : list[VendorMetricValue] | Nonevar vendor_metric_values_by_package : dict[str, list[VendorMetricValue]] | Nonevar viewability : Viewability | None
Inherited members
class PurgeKind (*args, **kwds)-
Expand source code
class PurgeKind(StrEnum): soft = 'soft' hard = 'hard'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var hardvar soft
class Purpose (*args, **kwds)-
Expand source code
class Purpose(StrEnum): platform_primary = 'platform_primary' measurement = 'measurement' attribution = 'attribution' creative_serving = 'creative_serving' identity = 'identity' other = 'other'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var attributionvar creative_servingvar identityvar measurementvar othervar platform_primary
class ReachWindow (**data: Any)-
Expand source code
class ReachWindow(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) kind: Annotated[ Kind, Field( description='Window kind. `cumulative` — no period field required. `period` and `rolling` — period field REQUIRED.' ), ] period: Annotated[ duration.Duration | None, Field( description="Duration of the measurement window. REQUIRED when kind is `period` or `rolling`. Matches the `period` field in delivery-metrics.json's reach_window block." ), ] = 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 kind : Kindvar model_configvar period : Duration | None
Inherited members
class RecordedCalls1 (**data: Any)-
Expand source code
class RecordedCalls1(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) method: Annotated[Method, Field(description='HTTP method of the outbound call.')] endpoint: Annotated[ str, Field( description="Composed `<METHOD> <URL>` string used for `endpoint_pattern` matching, e.g. 'POST https://api.tiktok.com/v2/audience/upload'. Convenience field — the runner can also reconstruct from `method` + URL components." ), ] url: Annotated[ AnyUrl, Field( description='Full URL of the outbound call (scheme + host + path + query). Treated as untrusted agent-controlled input by report renderers — see runner-output-contract.yaml > security.rendered_output_fencing.' ), ] host: Annotated[ str | None, Field( description='Host portion of the URL, useful for grouping calls by upstream platform.' ), ] = None path: Annotated[ str | None, Field(description='Path portion of the URL (without query string).') ] = None content_type: Annotated[ str, Field( description="Media type of the outbound request body, mirroring the agent's outbound `Content-Type` header (e.g., `application/json`, `application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain`). In raw mode this describes the returned `payload`; in digest mode it describes the body the digest was computed over. Storyboard `payload_must_contain` JSONPath-lite assertions are valid only when content_type is `application/json` or has a `+json` suffix AND attestation_mode is `raw` — digest mode and non-JSON content types grade `payload_must_contain` as not_applicable. Required so the runner can choose the right matcher deterministically." ), ] attestation_mode: Annotated[ Literal['raw'], Field( description="Per-call attestation mode echoing the request's `params.attestation_mode`. Required on every recorded_call so the `oneOf` discriminator always has an explicit value to dispatch on — no implicit defaults inside oneOf branches. Adopters MAY unilaterally downgrade a `raw` request to `digest` for a specific call when their policy requires it (e.g., the call carried regulated PII the adopter can't return raw). The runner reads this field to know which assertions to apply." ), ] = 'raw' purpose: Annotated[ Purpose | None, Field( description="Optional adopter-supplied semantic tag for the call's role. Values: `platform_primary` for the primary upstream platform the adapter is integrating with (e.g., a TikTok audience-upload call from a sales-social adapter); `measurement` for ancillary calls to measurement vendors (DV, IAS, Nielsen, MOAT); `attribution` for server-side conversion APIs (TTD Trans-API, Meta CAPI, AppsFlyer/Branch postbacks) that flow alongside primary platform calls in a buy-step; `creative_serving` for ad-server / CDN / tag-build calls (GAM tag generation, VAST/CDN fetches, creative trafficking); `identity` for ID-graph / hashing-service calls (LiveRamp, ID5, UID2); `other` for everything else (config fetches, internal telemetry, consent signal exchange). Lets storyboards scope `upstream_traffic` assertions via `purpose_filter` so a buyer-agent adapter that legitimately calls measurement vendors during a single buy step doesn't muddy the platform-primary assertion. Calls without a `purpose` field are treated as `purpose: other` for `purpose_filter` matching — adopters who haven't classified are matched only by storyboards filtering on `other` (or by storyboards with no `purpose_filter`). Self-reported, not adversarially trustworthy — same trust model as the rest of recorded_calls; misclassification by a façade is bounded by the runner's reporting of unclassified-call counts in `actual` when filters match zero." ), ] = None payload: Annotated[ Any, Field( description="Request body the agent sent. Required when `attestation_mode` is `raw` (or omitted); MUST be absent when `attestation_mode` is `digest`. Object when content_type is JSON-shaped and the controller decoded it; string otherwise. The `x-adcp-open-payload: true` annotation applies to the decoded JSON/object arm of this mixed field; non-JSON string payloads remain scalar values governed by the surrounding schema. Adopters MUST apply the recursive secret-key redaction described in this branch's top-level description before emission — secrets at any depth (Authorization values inlined into JSON bodies, embedded JWTs, presigned-URL tokens, OAuth refresh tokens) MUST be replaced with the literal string `[redacted]`. Storyboards that assert `payload_must_contain` or `identifier_paths` are matching against THIS field — secrets MUST be redacted but storyboard-supplied identifiers (hashed PII, request correlation values) MUST NOT be redacted. Adopters SHOULD cap individual payload size at 64 KiB; payloads exceeding that SHOULD be truncated with a trailing `[…truncated]` marker — large payloads bloat compliance reports and the LLM-rendered context windows that consume them.", max_length=65536, ), ] payload_digest_sha256: Annotated[ str | None, Field( description='SHA-256 digest of the canonicalized outbound request body, lowercase hex (64 chars). Required when `attestation_mode` is `digest`; MUST be absent when `attestation_mode` is `raw`. Canonicalization order is normative: (1) controllers MUST apply the recursive secret-key redaction (same pattern as the raw-mode payload field) BEFORE computing the digest; (2) for `application/json` and `*+json` content types, controllers MUST then serialize the redacted body to RFC 8785 (JCS) canonical form — sorted keys, no extraneous whitespace — and digest the resulting bytes. Storyboard-supplied identifiers (hashed PII, request correlation values) MUST NOT be redacted before digest computation; they are the load-bearing match target for `identifier_match_proofs` and digesting them away makes echo verification impossible. Both `payload_digest_sha256` AND `identifier_match_proofs` MUST be computed against the same post-redaction canonical bytes — diverging the two surfaces breaks coherence between digest replay and identifier echo. JCS edge cases: when a digest-mode `query_upstream_traffic` response cannot be produced because the parsed JSON-like value tree contains a non-finite numeric value (`NaN`, `+Infinity`, or `-Infinity`), controllers MUST NOT coerce that value to `null`, a string, or any other placeholder for digest computation; they MUST return the typed ControllerError code `JCS_NON_FINITE_NUMBER`. Runners MUST grade the affected upstream_traffic digest validation `not_applicable` because RFC 8785 forbids non-finite numbers. Payloads carrying numeric identifiers MUST serialize them as JSON strings before digest computation (adtech bid payloads regularly carry IDs outside ±2^53 where I-JSON / RFC 7493 number round-tripping diverges across implementations). For non-JSON content types the digest is computed over the post-redaction raw body bytes.', pattern='^[a-f0-9]{64}$', ), ] = None payload_length: Annotated[ SchemaInt, Field( description='Byte length of the post-redaction body bytes represented by this recorded_call. Required in both `raw` and `digest` modes — symmetric across modes so runners can detect adopter-side truncation regardless of attestation choice. In `raw` mode this MUST equal the UTF-8 byte length of the emitted `payload` value after the same recursive secret-key redaction the controller applied before returning it. In `digest` mode this MUST equal the exact number of bytes fed into SHA-256 for `payload_digest_sha256`: RFC 8785 (JCS) canonical bytes for JSON-shaped content after redaction, or the post-redaction raw body bytes for non-JSON content. Digest-mode `payload_length` is therefore NOT the original outbound body length before JSON parsing, redaction, or canonicalization. Mismatch between observed payload length and reported `payload_length` is a controller-side bug worth surfacing in the report.', ge=0, ), ] identifier_match_proofs: Annotated[ list[IdentifierMatchProof] | None, Field( description='Per-identifier echo proofs for digest-mode calls. Required when `attestation_mode` is `digest` AND the request supplied `params.identifier_value_digests`; MUST be absent or empty otherwise. Each entry corresponds to one digest from the request. Capped at 64 to match the request-side `params.identifier_value_digests` cap. Lets storyboards verify `identifier_paths` echo in digest mode without ever transmitting plaintext identifiers to the controller. SHA-256 is a privacy mechanism here, not a trust mechanism — controllers self-report `found` and a determined façade can return any boolean; consumers MUST NOT treat digest-mode passing as cryptographically more trustworthy than raw mode. Tokenization is normative: for `application/json` and `*+json` content types, controllers MUST scan exactly the JSON string-typed leaf values of the post-redaction canonicalized body — no substring matching, no word splitting, no case folding, no Unicode normalization. A token matches when its SHA-256 hash equals one of the requested digests byte-for-byte. For non-JSON content types (form-urlencoded, multipart, plain text), `identifier_match_proofs` MUST be empty and runner-side `identifier_paths` assertions targeting those calls grade `not_applicable` — token boundaries are not portably defined across non-JSON shapes.', max_length=64, ), ] = None timestamp: Annotated[ AwareDatetime, Field( description="ISO 8601 timestamp the adopter recorded the outbound call. MUST reflect the adopter's wall clock at the moment the outbound request was sent (not log-flush time), and MUST be monotonically non-decreasing across recorded_calls of a single response. Used by runners to scope assertions to a specific storyboard step's window — see runner-output-contract.yaml > validation_result for the timestamp boundary semantics." ), ] status_code: Annotated[ SchemaInt | None, Field( description='HTTP status code returned by the upstream. Optional — adopters MAY omit when the call was instrumented before the response arrived.', ge=100, le=599, ), ] = 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 attestation_mode : Literal['raw']var content_type : strvar endpoint : strvar host : str | Nonevar identifier_match_proofs : list[IdentifierMatchProof] | Nonevar method : Methodvar model_configvar path : str | Nonevar payload : Anyvar payload_digest_sha256 : str | Nonevar payload_length : intvar purpose : Purpose | Nonevar status_code : int | Nonevar timestamp : pydantic.types.AwareDatetimevar url : pydantic.networks.AnyUrl
Inherited members
class RecordedCalls2 (**data: Any)-
Expand source code
class RecordedCalls2(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) method: Annotated[Method, Field(description='HTTP method of the outbound call.')] endpoint: Annotated[ str, Field( description="Composed `<METHOD> <URL>` string used for `endpoint_pattern` matching, e.g. 'POST https://api.tiktok.com/v2/audience/upload'. Convenience field — the runner can also reconstruct from `method` + URL components." ), ] url: Annotated[ AnyUrl, Field( description='Full URL of the outbound call (scheme + host + path + query). Treated as untrusted agent-controlled input by report renderers — see runner-output-contract.yaml > security.rendered_output_fencing.' ), ] host: Annotated[ str | None, Field( description='Host portion of the URL, useful for grouping calls by upstream platform.' ), ] = None path: Annotated[ str | None, Field(description='Path portion of the URL (without query string).') ] = None content_type: Annotated[ str, Field( description="Media type of the outbound request body, mirroring the agent's outbound `Content-Type` header (e.g., `application/json`, `application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain`). In raw mode this describes the returned `payload`; in digest mode it describes the body the digest was computed over. Storyboard `payload_must_contain` JSONPath-lite assertions are valid only when content_type is `application/json` or has a `+json` suffix AND attestation_mode is `raw` — digest mode and non-JSON content types grade `payload_must_contain` as not_applicable. Required so the runner can choose the right matcher deterministically." ), ] attestation_mode: Annotated[ Literal['digest'], Field( description="Per-call attestation mode echoing the request's `params.attestation_mode`. Required on every recorded_call so the `oneOf` discriminator always has an explicit value to dispatch on — no implicit defaults inside oneOf branches. Adopters MAY unilaterally downgrade a `raw` request to `digest` for a specific call when their policy requires it (e.g., the call carried regulated PII the adopter can't return raw). The runner reads this field to know which assertions to apply." ), ] = 'digest' purpose: Annotated[ Purpose | None, Field( description="Optional adopter-supplied semantic tag for the call's role. Values: `platform_primary` for the primary upstream platform the adapter is integrating with (e.g., a TikTok audience-upload call from a sales-social adapter); `measurement` for ancillary calls to measurement vendors (DV, IAS, Nielsen, MOAT); `attribution` for server-side conversion APIs (TTD Trans-API, Meta CAPI, AppsFlyer/Branch postbacks) that flow alongside primary platform calls in a buy-step; `creative_serving` for ad-server / CDN / tag-build calls (GAM tag generation, VAST/CDN fetches, creative trafficking); `identity` for ID-graph / hashing-service calls (LiveRamp, ID5, UID2); `other` for everything else (config fetches, internal telemetry, consent signal exchange). Lets storyboards scope `upstream_traffic` assertions via `purpose_filter` so a buyer-agent adapter that legitimately calls measurement vendors during a single buy step doesn't muddy the platform-primary assertion. Calls without a `purpose` field are treated as `purpose: other` for `purpose_filter` matching — adopters who haven't classified are matched only by storyboards filtering on `other` (or by storyboards with no `purpose_filter`). Self-reported, not adversarially trustworthy — same trust model as the rest of recorded_calls; misclassification by a façade is bounded by the runner's reporting of unclassified-call counts in `actual` when filters match zero." ), ] = None payload: Annotated[ Any | None, Field( description="Request body the agent sent. Required when `attestation_mode` is `raw` (or omitted); MUST be absent when `attestation_mode` is `digest`. Object when content_type is JSON-shaped and the controller decoded it; string otherwise. The `x-adcp-open-payload: true` annotation applies to the decoded JSON/object arm of this mixed field; non-JSON string payloads remain scalar values governed by the surrounding schema. Adopters MUST apply the recursive secret-key redaction described in this branch's top-level description before emission — secrets at any depth (Authorization values inlined into JSON bodies, embedded JWTs, presigned-URL tokens, OAuth refresh tokens) MUST be replaced with the literal string `[redacted]`. Storyboards that assert `payload_must_contain` or `identifier_paths` are matching against THIS field — secrets MUST be redacted but storyboard-supplied identifiers (hashed PII, request correlation values) MUST NOT be redacted. Adopters SHOULD cap individual payload size at 64 KiB; payloads exceeding that SHOULD be truncated with a trailing `[…truncated]` marker — large payloads bloat compliance reports and the LLM-rendered context windows that consume them.", max_length=65536, ), ] = None payload_digest_sha256: Annotated[ str, Field( description='SHA-256 digest of the canonicalized outbound request body, lowercase hex (64 chars). Required when `attestation_mode` is `digest`; MUST be absent when `attestation_mode` is `raw`. Canonicalization order is normative: (1) controllers MUST apply the recursive secret-key redaction (same pattern as the raw-mode payload field) BEFORE computing the digest; (2) for `application/json` and `*+json` content types, controllers MUST then serialize the redacted body to RFC 8785 (JCS) canonical form — sorted keys, no extraneous whitespace — and digest the resulting bytes. Storyboard-supplied identifiers (hashed PII, request correlation values) MUST NOT be redacted before digest computation; they are the load-bearing match target for `identifier_match_proofs` and digesting them away makes echo verification impossible. Both `payload_digest_sha256` AND `identifier_match_proofs` MUST be computed against the same post-redaction canonical bytes — diverging the two surfaces breaks coherence between digest replay and identifier echo. JCS edge cases: when a digest-mode `query_upstream_traffic` response cannot be produced because the parsed JSON-like value tree contains a non-finite numeric value (`NaN`, `+Infinity`, or `-Infinity`), controllers MUST NOT coerce that value to `null`, a string, or any other placeholder for digest computation; they MUST return the typed ControllerError code `JCS_NON_FINITE_NUMBER`. Runners MUST grade the affected upstream_traffic digest validation `not_applicable` because RFC 8785 forbids non-finite numbers. Payloads carrying numeric identifiers MUST serialize them as JSON strings before digest computation (adtech bid payloads regularly carry IDs outside ±2^53 where I-JSON / RFC 7493 number round-tripping diverges across implementations). For non-JSON content types the digest is computed over the post-redaction raw body bytes.', pattern='^[a-f0-9]{64}$', ), ] payload_length: Annotated[ SchemaInt, Field( description='Byte length of the post-redaction body bytes represented by this recorded_call. Required in both `raw` and `digest` modes — symmetric across modes so runners can detect adopter-side truncation regardless of attestation choice. In `raw` mode this MUST equal the UTF-8 byte length of the emitted `payload` value after the same recursive secret-key redaction the controller applied before returning it. In `digest` mode this MUST equal the exact number of bytes fed into SHA-256 for `payload_digest_sha256`: RFC 8785 (JCS) canonical bytes for JSON-shaped content after redaction, or the post-redaction raw body bytes for non-JSON content. Digest-mode `payload_length` is therefore NOT the original outbound body length before JSON parsing, redaction, or canonicalization. Mismatch between observed payload length and reported `payload_length` is a controller-side bug worth surfacing in the report.', ge=0, ), ] identifier_match_proofs: Annotated[ list[IdentifierMatchProof] | None, Field( description='Per-identifier echo proofs for digest-mode calls. Required when `attestation_mode` is `digest` AND the request supplied `params.identifier_value_digests`; MUST be absent or empty otherwise. Each entry corresponds to one digest from the request. Capped at 64 to match the request-side `params.identifier_value_digests` cap. Lets storyboards verify `identifier_paths` echo in digest mode without ever transmitting plaintext identifiers to the controller. SHA-256 is a privacy mechanism here, not a trust mechanism — controllers self-report `found` and a determined façade can return any boolean; consumers MUST NOT treat digest-mode passing as cryptographically more trustworthy than raw mode. Tokenization is normative: for `application/json` and `*+json` content types, controllers MUST scan exactly the JSON string-typed leaf values of the post-redaction canonicalized body — no substring matching, no word splitting, no case folding, no Unicode normalization. A token matches when its SHA-256 hash equals one of the requested digests byte-for-byte. For non-JSON content types (form-urlencoded, multipart, plain text), `identifier_match_proofs` MUST be empty and runner-side `identifier_paths` assertions targeting those calls grade `not_applicable` — token boundaries are not portably defined across non-JSON shapes.', max_length=64, ), ] = None timestamp: Annotated[ AwareDatetime, Field( description="ISO 8601 timestamp the adopter recorded the outbound call. MUST reflect the adopter's wall clock at the moment the outbound request was sent (not log-flush time), and MUST be monotonically non-decreasing across recorded_calls of a single response. Used by runners to scope assertions to a specific storyboard step's window — see runner-output-contract.yaml > validation_result for the timestamp boundary semantics." ), ] status_code: Annotated[ SchemaInt | None, Field( description='HTTP status code returned by the upstream. Optional — adopters MAY omit when the call was instrumented before the response arrived.', ge=100, le=599, ), ] = 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 attestation_mode : Literal['digest']var content_type : strvar endpoint : strvar host : str | Nonevar identifier_match_proofs : list[IdentifierMatchProof] | Nonevar method : Methodvar model_configvar path : str | Nonevar payload : typing.Any | Nonevar payload_digest_sha256 : strvar payload_length : intvar purpose : Purpose | Nonevar status_code : int | Nonevar timestamp : pydantic.types.AwareDatetimevar url : pydantic.networks.AnyUrl
Inherited members
class ReportedSpend (**data: Any)-
Expand source code
class ReportedSpend(AdCPBaseModel): amount: Annotated[StrictFloat, Field(ge=0.0)] currency: Annotated[str, Field(pattern='^[A-Z]{3}$')]Base model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas 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 amount : floatvar currency : strvar model_config
Inherited members
class TargetHealth (*args, **kwds)-
Expand source code
class TargetHealth(StrEnum): delayed = 'delayed' action_required = 'action_required'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var action_requiredvar delayed