Module adcp.types.domains.core.package
Classes
class Cancellation (**data: Any)-
Expand source code
class Cancellation(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) canceled_at: Annotated[ AwareDatetime, Field(description='ISO 8601 timestamp when this package was canceled.') ] canceled_by: Annotated[ canceled_by_1.CanceledBy, Field(description='Which party initiated the package cancellation.'), ] reason: Annotated[ str | None, Field(description='Reason the package was canceled.', max_length=500) ] = None acknowledged_at: Annotated[ AwareDatetime | None, Field( description='ISO 8601 timestamp when the seller acknowledged the cancellation. Confirms inventory has been released and billing stopped. Absent until the seller processes the cancellation.' ), ] = 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 acknowledged_at : pydantic.types.AwareDatetime | Nonevar canceled_at : pydantic.types.AwareDatetimevar canceled_by : CanceledByvar model_configvar reason : str | None
Inherited members
class Package (**data: Any)-
Expand source code
class Package(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) package_id: Annotated[str, Field(description="Seller's unique identifier for the package")] product_id: Annotated[ str | None, Field( description="ID of the product this package is based on. For packages created from an explicit create_media_buy package request, sellers MUST echo the request package's product_id on every response package object that represents that requested package." ), ] = None audience_evidence_selections: Annotated[ list[audience_evidence_selection.AudienceEvidenceSelection] | None, Field( description='Exact immutable audience-evidence snapshots that affected recommendation, eligibility, or package construction. A confirmed package MUST include a package_construction selection matching every buyer audience_evidence_pin and every snapshot used to satisfy package audience_evidence_requirements; this readback remains mandatory on subsequent package read surfaces. This is decision provenance only; applied targeting remains exclusively in targeting_overlay and targeting_resolution.demographics.', min_length=1, ), ] = None budget: Annotated[ StrictFloat | None, Field( description='Hard lifetime spend cap for this package in the media-buy currency. Every selected pricing option in an AdCP-authored media buy MUST declare that same currency. In seller-optimized allocation mode this is a ceiling, not a current allocation. May be omitted when the package is bounded only by the shared media-buy total.', ge=0.0, ), ] = None min_spend_target: Annotated[ StrictFloat | None, Field( description='Soft lifetime spend target accepted for this package under seller-optimized budget allocation. This is an allocation preference, not a billing or delivery guarantee.', ge=0.0, ), ] = None daily_budget_cap: Annotated[ StrictFloat | None, Field( description="The hard package spend ceiling per shared media-buy cap day, in the media buy's currency. Sellers MUST echo this whenever a package daily cap is set. It is a subordinate ceiling, not a reserved or current allocation; the media buy's budget_cap_timezone defines its day boundary.", ge=0.0, ), ] = None pacing: pacing_1.Pacing | None = None pricing_option_id: Annotated[ str | None, Field( description="ID of the selected pricing option from the product's pricing_options array" ), ] = None bid_price: Annotated[ StrictFloat | None, Field( deprecated=True, description='DEPRECATED legacy bidding representation. 3.2 sellers normalize accepted legacy input and SHOULD echo bidding instead. Removed in the next major.', ge=0.0, ), ] = None bidding: Annotated[ bidding_policy.BiddingPolicy | None, Field( description='Package-authored bidding policy, echoed only when the buyer authored a package override. `{automatic:true}` is an explicit automatic-bidding override. Omission means the package inherits media-buy bidding or, when both scopes are absent, uses provider automatic delivery. Monetary fields are denominated in the media-buy currency. Sellers MUST NOT materialize inherited media-buy policy here.' ), ] = None price_breakdown: Annotated[ price_breakdown_1.PriceBreakdown | None, Field( description="Breakdown of the effective price for this package. On fixed-price packages, echoes the pricing option's breakdown. On auction packages, shows the clearing price breakdown including any commission or settlement terms." ), ] = None impressions: Annotated[ StrictFloat | None, Field(description='Impression goal for this package', ge=0.0) ] = None catalogs: Annotated[ list[catalog.Catalog] | None, Field( description='Catalogs this package promotes. Each catalog MUST have a distinct type (e.g., one product catalog, one store catalog). This constraint is enforced at the application level — sellers MUST reject requests containing multiple catalogs of the same type with a validation_error. Echoed from the create_media_buy request.' ), ] = None format_ids: Annotated[ list[format_id.FormatReferenceStructuredObject] | None, Field( deprecated=True, description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Legacy named-format IDs supplied for this package on create_media_buy. Sellers SHOULD echo this field whenever the request included it, including dual-emission cases where `format_option_refs` was the winning selector, so read surfaces preserve the original wire contract. Omitted means the request did not carry legacy format_ids unless the seller cannot reconstruct legacy requests created before this field was persisted.', ), ] = None format_option_refs: Annotated[ list[format_option_ref.FormatOptionReference] | None, Field( description='Structured 3.1+ format option references supplied for this package on create_media_buy. Sellers SHOULD echo this field whenever the request included it. Publisher-catalog-backed options are identified by `{ scope: "publisher", publisher_domain, format_option_id }`; product-local options are identified by `{ scope: "product", format_option_id }` and resolve only against this package\'s target product. Omitted means the request did not carry format_option_refs unless the seller cannot reconstruct legacy requests created before this field was persisted.', min_length=1, ), ] = None format_kind: Annotated[ str | None, Field( description='Direct canonical selector supplied for this package on create_media_buy. Sellers SHOULD echo this field whenever the request included it, including informational-echo cases where `format_ids` was the winning selector, so read surfaces preserve the original wire contract.' ), ] = None params: Annotated[ dict[str, Any] | None, Field( description='Parameters for the direct canonical selector in `format_kind`, echoed from the create_media_buy request whenever the request included it. Requires `format_kind`; omitted only when the request did not carry direct canonical params or when the seller cannot reconstruct legacy requests created before this field was persisted.' ), ] = None targeting_overlay: Annotated[ targeting.TargetingOverlay | None, Field( description='Complete effective targeting accepted for this package, including targeting bound through configured product selection plus package-specific targeting. Sellers MUST echo an applied package frequency_cap independently from any MediaBuy root cap. Sellers MUST also echo placement, property, and collection selection so buyers can audit purchased inventory: placements via placement_selection, collections via collection_selection (the committed concrete selectors, materialized even when the selection was produced through collection_list references).' ), ] = None targeting_resolution: Annotated[ package_targeting_resolution.PackageTargetingResolution | None, Field( description="Execution details for the package's accepted targeting. Sellers MUST include targeting_resolution.demographics whenever demographic targeting was requested or applied." ), ] = None measurement_terms: Annotated[ measurement_terms_1.MeasurementTerms | None, Field( description="Agreed billing measurement and makegood terms for this package. Reflects what was negotiated — may differ from the buyer's proposal or the product's defaults. When present, these terms are binding for the package's duration." ), ] = None performance_standards: Annotated[ list[performance_standard.PerformanceStandard] | None, Field( description='Agreed performance standards for this package. When any entry specifies a vendor, creatives assigned to this package MUST include corresponding tracker_script or tracker_pixel assets from that vendor.', min_length=1, ), ] = None committed_metrics: Annotated[ list[committed_metric.CommittedMetric] | None, Field( description="The binding reporting contract for this package — what the seller has agreed to populate in delivery reports. Each entry carries an explicit `committed_at` timestamp, so the array also serves as the contract amendment ledger: day-1 commitments share `committed_at = create_media_buy.confirmed_at`; mid-flight additions carry their own timestamps. When `create_media_buy.confirmed_at` is null for a provisional buy, sellers MUST omit `committed_metrics` until commitment. The first response that sets `confirmed_at` MAY include the initial committed-metrics set, and each such entry's `committed_at` MUST equal `confirmed_at`. The `missing_metrics` field on `get_media_buy_delivery` reconciles against this list, filtering to entries where `committed_at < reporting_period.end` (a metric committed mid-flight is only audited from its commitment timestamp forward). Sellers stamp the day-1 set on the `create_media_buy` response; mid-flight additions are appended via `update_media_buy` (append-only — sellers MUST reject attempts to modify or remove existing entries with `validation_error`, suggested code: `IMMUTABLE_FIELD`). Optional in v1; absence means the seller does not provide an audit-grade contract and `missing_metrics` falls back to the product's live `available_metrics` (a known audit gap — buyers SHOULD treat absence as 'no audit-grade contract' rather than 'clean delivery'). Each entry uses an explicit `scope` discriminator: `standard` for entries from the closed `available-metric.json` enum, `vendor` for vendor-defined metrics anchored on a BrandRef. Standard entries are symmetric with `by_package[].metric_values`; vendor entries reconcile to `by_package[].vendor_metric_values`; both use `by_package[].missing_metrics` for gaps. The atomic key remains `(scope, metric_id, qualifier)`, with vendor identity included for vendor scope. Replaces the parallel-array design that shipped briefly in #3510.", examples=[ [ { 'scope': 'standard', 'metric_id': 'impressions', 'committed_at': '2026-04-29T10:53:00Z', }, { 'scope': 'standard', 'metric_id': 'spend', 'committed_at': '2026-04-29T10:53:00Z', }, { 'scope': 'standard', 'metric_id': 'completed_views', 'committed_at': '2026-04-29T10:53:00Z', }, { 'scope': 'vendor', 'vendor': {'domain': 'attentionvendor.example'}, 'metric_id': 'attention_units', 'committed_at': '2026-04-29T10:53:00Z', }, { 'scope': 'standard', 'metric_id': 'viewable_rate', 'qualifier': {'viewability_standard': 'mrc'}, 'committed_at': '2026-05-30T14:22:00Z', }, ] ], min_length=1, ), ] = None creative_assignments: Annotated[ list[creative_assignment.CreativeAssignment] | None, Field( description='Creative assets assigned to this package, including the committed package-scoped rotation policy. Omitted rotation_mode reads as weighted for backward compatibility; all assignments resolve to one effective mode, and sequential positions are unique within each package-local group.' ), ] = None formats_to_provide: Annotated[ list[package_format_snapshot.PackageFormatSnapshot] | None, Field( description='Immutable canonical creative contracts established for this package. Each entry is a PackageFormatSnapshot of the selected effective Product format declaration. A package whose selected format carries tracker_execution_contract MUST retain and return this checklist even after creative coverage is complete; the live Product is never substituted for the package snapshot.', min_length=1, ), ] = None formats_pending: Annotated[ list[package_format_snapshot.PackageFormatSnapshot] | None, Field( description='PackageFormatSnapshot entries from formats_to_provide that do not yet have creative coverage through sync_creatives or inline assignment. Every entry MUST equal its formats_to_provide snapshot after RFC 8785 canonicalization and, when product_snapshot_digest is present, carry the identical digest. An empty emitted array means every required format is covered. Absence means readiness was not reported.' ), ] = None format_ids_to_provide: Annotated[ list[format_id.FormatReferenceStructuredObject] | None, Field( deprecated=True, description='**DEPRECATED in 3.2.** Legacy named-format projection of formats_to_provide retained for older 3.x peers. New sellers emit canonical formats_to_provide declarations.', ), ] = None format_ids_pending: Annotated[ list[format_id.FormatReferenceStructuredObject] | None, Field( deprecated=True, description='**DEPRECATED in 3.2.** Legacy named-format projection of formats_pending retained for older 3.x peers. New sellers emit canonical formats_pending declarations. An empty emitted array means every projected requirement is covered. Absence means legacy readiness was not reported and MUST NOT be interpreted as full coverage.', ), ] = None optimization_goals: Annotated[ list[optimization_goal.OptimizationGoal] | None, Field( description='Optimization targets for this package. The seller optimizes delivery toward these goals in priority order. Common pattern: event goals (purchase, install) as primary targets at priority 1; metric goals (clicks, views) as secondary proxy signals at priority 2+.', min_length=1, ), ] = None start_time: Annotated[ AwareDatetime | None, Field( description="Flight start date/time for this package in ISO 8601 format. When omitted, the package inherits the media buy's start_time. Sellers SHOULD always include the resolved value in responses, even when inherited." ), ] = None end_time: Annotated[ AwareDatetime | None, Field( description="Flight end date/time for this package in ISO 8601 format. When omitted, the package inherits the media buy's end_time. Sellers SHOULD always include the resolved value in responses, even when inherited." ), ] = None paused: Annotated[ StrictBool | None, Field( description='Whether this package is paused by the buyer. Paused packages do not deliver impressions. Defaults to false.' ), ] = False canceled: Annotated[ StrictBool | None, Field( description='Whether this package has been canceled. Canceled packages stop delivery and cannot be reactivated. Defaults to false.' ), ] = False cancellation: Annotated[ Cancellation | None, Field(description='Cancellation metadata. Present only when canceled is true.'), ] = None agency_estimate_number: Annotated[ str | None, Field( description="Agency estimate or authorization number for this package. Echoed from the buyer's request. When present on the package, takes precedence over the media buy-level estimate number.", max_length=100, ), ] = None creative_deadline: Annotated[ AwareDatetime | None, Field( description="ISO 8601 timestamp for creative upload or change deadline for this package. After this deadline, creative changes are rejected. When absent, the media buy's creative_deadline applies." ), ] = None context: Annotated[ context_1.ContextObject | None, Field( description='Opaque package-level correlation data echoed unchanged in responses, webhooks, and read surfaces. Buyers targeting mixed seller populations SHOULD include a per-package correlation value here, commonly context.buyer_ref, so responses from legacy sellers that do not echo product_id can still be mapped back to the requested product or line item. Sellers MUST preserve this object unchanged and MUST NOT parse it for business logic.' ), ] = None ext: ext_1.ExtensionObject | None = 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 agency_estimate_number : str | Nonevar audience_evidence_selections : list[AudienceEvidenceSelection] | Nonevar bid_price : float | Nonevar bidding : BiddingPolicy | Nonevar budget : float | Nonevar canceled : bool | Nonevar cancellation : Cancellation | Nonevar catalogs : list[Catalog] | Nonevar committed_metrics : list[CommittedMetric1 | CommittedMetric2] | Nonevar context : ContextObject | Nonevar creative_assignments : list[CreativeAssignment] | Nonevar creative_deadline : pydantic.types.AwareDatetime | Nonevar daily_budget_cap : float | Nonevar end_time : pydantic.types.AwareDatetime | Nonevar ext : ExtensionObject | Nonevar format_ids : list[FormatReferenceStructuredObject] | Nonevar format_ids_pending : list[FormatReferenceStructuredObject] | Nonevar format_ids_to_provide : list[FormatReferenceStructuredObject] | Nonevar format_kind : str | Nonevar format_option_refs : list[FormatOptionReference1 | FormatOptionReference2] | Nonevar formats_pending : list[PackageFormatSnapshot18 | PackageFormatSnapshot19 | PackageFormatSnapshot20 | PackageFormatSnapshot21 | PackageFormatSnapshot22 | PackageFormatSnapshot23 | PackageFormatSnapshot24 | PackageFormatSnapshot25 | PackageFormatSnapshot26 | PackageFormatSnapshot27 | PackageFormatSnapshot28 | PackageFormatSnapshot29 | PackageFormatSnapshot30 | PackageFormatSnapshot31 | PackageFormatSnapshot32 | PackageFormatSnapshot33] | Nonevar formats_to_provide : list[PackageFormatSnapshot18 | PackageFormatSnapshot19 | PackageFormatSnapshot20 | PackageFormatSnapshot21 | PackageFormatSnapshot22 | PackageFormatSnapshot23 | PackageFormatSnapshot24 | PackageFormatSnapshot25 | PackageFormatSnapshot26 | PackageFormatSnapshot27 | PackageFormatSnapshot28 | PackageFormatSnapshot29 | PackageFormatSnapshot30 | PackageFormatSnapshot31 | PackageFormatSnapshot32 | PackageFormatSnapshot33] | Nonevar impressions : float | Nonevar measurement_terms : MeasurementTerms | Nonevar min_spend_target : float | Nonevar model_configvar optimization_goals : list[OptimizationGoal8 | OptimizationGoal9 | OptimizationGoal10] | Nonevar pacing : Pacing | Nonevar package_id : strvar params : dict[str, typing.Any] | Nonevar paused : bool | Nonevar performance_standards : list[PerformanceStandard] | Nonevar price_breakdown : PriceBreakdown | Nonevar pricing_option_id : str | Nonevar product_id : str | Nonevar start_time : pydantic.types.AwareDatetime | Nonevar targeting_overlay : TargetingOverlay | Nonevar targeting_resolution : PackageTargetingResolution | None
Inherited members