Module adcp.types.domains.account.report_usage_request
Classes
class ReportUsageRequest (**data: Any)-
Expand source code
class ReportUsageRequest(AdcpRequest, AdcpVersionEnvelope): model_config = ConfigDict( extra='allow', ) idempotency_key: Annotated[ str, Field( description='Client-generated unique key for this request. If a request with the same key has already been accepted, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request. Prevents duplicate billing on retries.' ), ] reporting_period: Annotated[ datetime_range.DatetimeRange, Field( description='The time range covered by this usage report. Applies to all records in the request.' ), ] usage: Annotated[ list[UsageItem], Field( description='One or more usage records. Each record is self-contained: it carries its own account, allowing a single request to span multiple accounts.', min_length=1, ), ] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = NoneThe request message of a task in the pinned bundle's task registry.
A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is.
issubclass(model, AdcpRequest)is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.Each accessor returns the field's value, or
Nonewhen this tool's schema declares no such field. Only 49 of the 87 request schemas declare anaccountand only 43 anidempotency_key, so asking the request is what replacesgetattr(req, "account", None)againstAnyat the boundary.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdcpRequest
- adcp.types.base._AdcpMessage
- AdcpVersionEnvelope
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var context : ContextObject | Nonevar ext : ExtensionObject | Nonevar idempotency_key : strvar model_configvar reporting_period : DatetimeRangevar usage : list[UsageItem]
Inherited members
class UsageItem (**data: Any)-
Expand source code
class UsageItem(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) account: Annotated[ account_ref.AccountReference, Field(description='Account for this usage record.') ] media_buy_id: Annotated[ str | None, Field( description='Seller-assigned media buy identifier. Links this usage record to a specific media buy.' ), ] = None vendor_cost: Annotated[ StrictFloat, Field( description='Amount owed to the vendor for this record, denominated in currency.', ge=0.0, ), ] currency: Annotated[str, Field(description='ISO 4217 currency code.', pattern='^[A-Z]{3}$')] pricing_option_id: Annotated[ str | None, Field( description="Pricing option identifier from the vendor's discovery response (e.g., get_signals, list_content_standards). The vendor uses this to verify the correct rate was applied." ), ] = None impressions: Annotated[ SchemaInt | None, Field(description='Impressions delivered using this vendor service.', ge=0), ] = None media_spend: Annotated[ StrictFloat | None, Field( description='Media spend in currency for the period. Required when a percent_of_media pricing model was used, so the vendor can verify the applied rate.', ge=0.0, ), ] = None conversions: Annotated[ StrictFloat | None, Field( description='Number of attributed conversion events for the reporting period. Optional analytics context for revenue_share reconciliation.', ge=0.0, ), ] = None conversion_value: Annotated[ StrictFloat | None, Field( description='Total monetary value of attributed conversions for the reporting period, in currency. Optional analytics context for revenue_share reconciliation; it is not the billing basis.', ge=0.0, ), ] = None commissionable_value: Annotated[ StrictFloat | None, Field( description='Settled attributed value eligible for commission, in currency. Required when pricing_option_id selects a revenue_share option. The receiver verifies vendor_cost = round_currency(commissionable_value × the selected commission_rate).', ge=0.0, ), ] = None signal_agent_segment_id: Annotated[ str | None, Field(description='Signal identifier from get_signals. Required for signals agents.'), ] = None standards_id: Annotated[ str | None, Field( description='Content standards configuration identifier. Required for governance agents.' ), ] = None rights_id: Annotated[ str | None, Field( description='Rights grant identifier from acquire_rights. Required for brand/rights agents. Links usage records to specific rights grants for cap tracking, billing verification, and overage calculation.' ), ] = None creative_id: Annotated[ str | None, Field( description='Creative identifier from build_creative or list_creatives. Required for creative agents. Links usage records to specific creatives for billing verification.' ), ] = None build_variant_id: Annotated[ str | None, Field( description='Optional. When the reported creative_id was promoted from a specific build_creative variant leaf but the creative_id differs from the source build_variant_id, carry that source build_variant_id so billing reconciliation can link this usage record back to the exact produced leaf for audit (pricing_option_id alone is not unique across leaves). On the canonical path where creative_id is the build_variant_id, omit this field and use creative_id as the join key. Omit for creatives with no build-variant lineage.' ), ] = None property_list_id: Annotated[ str | None, Field( description='Property list identifier from list_property_lists. Required for property list agents. Links usage records to specific property lists for billing verification.' ), ] = None final: Annotated[ StrictBool | None, Field( description="Whether this usage record represents the reporter's final, billing-authoritative numbers for the reporting period. **Absent means unknown** — the reporter has not declared finality on this record. Set `true` only when the reporter has actually settled the numbers (e.g., 3PAS month-end close after SIVT scrubbing, conversion dedup, and view-through windows have closed; vendor file post-C7 for broadcast). Set `false` when pushing preliminary measurements (daily pacing pushes, intra-period progress) that are still settling. Receivers MUST NOT invoice on `final: false` records, and MUST NOT invoice on records where `final` is absent for buys whose `measurement_terms.billing_measurement` names this reporter as authoritative — request a final record first. Receivers MAY invoice on absent for buys with no `measurement_terms.billing_measurement` (3.0-style usage where the receiver treats reports as authoritative on receipt) and for non-media-buy variants (signals, governance, creative, brand — domains with no provisional state concept). When the same `(account, media_buy_id, reporting_period)` is later reported with `final: true`, that record supersedes any prior records for the period." ), ] = None finalized_at: Annotated[ AwareDatetime | None, Field( description="ISO 8601 timestamp at which the reporter considered these numbers final. Present only when `final: true`. Anchors any deadline declared in the buy's `measurement_terms.billing_measurement.finalization_deadline_hours`." ), ] = None measurement_window: Annotated[ str | None, Field( description="Which measurement window this record represents, referencing a window_id from the product's reporting_capabilities.measurement_windows or from `measurement_terms.billing_measurement.measurement_window`. Examples: 'c7' for broadcast TV, 'post_sivt' for digital post-IVT, 'downloads_30d' for podcast. When absent, the record is not windowed (standard digital reporting). When the buy's `measurement_terms.billing_measurement.measurement_window` is set, reporters SHOULD include `measurement_window` so the receiver can reconcile against the correct stage.", examples=['live', 'c3', 'c7', 'post_ivt', 'post_sivt', 'downloads_30d'], max_length=50, ), ] = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var account : AccountReference1 | AccountReference2var build_variant_id : str | Nonevar commissionable_value : float | Nonevar conversion_value : float | Nonevar conversions : float | Nonevar creative_id : str | Nonevar currency : strvar final : bool | Nonevar finalized_at : pydantic.types.AwareDatetime | Nonevar impressions : int | Nonevar measurement_window : str | Nonevar media_buy_id : str | Nonevar media_spend : float | Nonevar model_configvar pricing_option_id : str | Nonevar property_list_id : str | Nonevar rights_id : str | Nonevar signal_agent_segment_id : str | Nonevar standards_id : str | Nonevar vendor_cost : float
Inherited members