Optionalproposal_id?: stringSeller's unique identifier for the created media buy
Optionalname?: stringPersisted human-readable name for this media buy. When create_media_buy supplied name, the seller MUST echo it unchanged here. This display label is shared for trafficking UI display and operational communication; it is not an identifier or financial reference.
Optionalaccount?: {Unique identifier for this account
Human-readable account name (e.g., 'Acme', 'Acme c/o Pinnacle')
Optionaladvertiser?: stringThe advertiser whose rates apply to this account
Optionalbilling_proxy?: stringOptional intermediary who receives invoices on behalf of the advertiser (e.g., agency)
Optionalbrand?: {Domain where /.well-known/brand.json is hosted, or the brand's operating domain
Optionalbrand_id?: stringOptionalcountries?: string[]Canonical set of ISO 3166-1 alpha-2 countries for this advertiser identity. Omit for a global/default identity. Array order is not meaningful; producers MUST sort codes lexicographically before computing keys or signatures. This qualifies account identity and is not delivery targeting.
Optionalindustries?: string[]Inline override for the brand's industries. Useful when the caller cannot modify the brand's canonical brand.json but needs to declare industries for governance (e.g., Annex III vertical detection). brand.json remains the canonical source; when omitted here, governance agents SHOULD resolve from brand.json.
Optionaldata_subject_contestation?: { url?: string; email?: string; languages?: string[] }Inline override for the brand's contestation contact point. Useful when the operator does not control brand.json but needs to discharge Art 22(3) for this plan. brand.json is canonical; when omitted, governance agents resolve brand → house → missing.
Optionalurl?: stringOptionalemail?: stringOptionallanguages?: string[]Optionalbrand_kit_override?: {Inline override for brand-kit fields normally resolved from /.well-known/brand.json on domain (logo, colors, voice, tagline). Use when brand.json is missing, stale, or inappropriate for this specific call — e.g., a campaign-scoped tagline, a co-branded creative, a freshly-rebranded color palette the brand.json hasn't shipped yet. Same inline-override pattern as industries and data_subject_contestation above: brand.json is canonical, the override is per-call. Adopters needing to override fields outside this subset (voice_attributes, prohibited_terms, etc.) MUST publish a different brand.json and reference it via a different domain — the inline override is intentionally narrow to a small high-traffic subset.
Merge semantics (normative). The merge is field-level, not whole-object replacement. Each field within brand_kit_override (logo, colors, voice, tagline) is evaluated independently — when a field is present on the override the override value applies; when a field is absent the brand.json value applies (or is absent if brand.json doesn't carry one either). For composite fields (colors.primary, colors.secondary, colors.accent), the merge is one level deeper: each color slot is evaluated independently — a producer can override colors.primary while still inheriting colors.secondary from brand.json. SDKs MUST NOT treat a present brand_kit_override.colors as wiping the brand.json colors block entirely; only the per-slot fields present in the override take precedence. Without this rule, a partial-override semantics would diverge across SDKs and produce inconsistent rendering for the same payload.
Optionallogo?: {Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry.
URL to the image asset
Width in pixels
Height in pixels
Optionalfile_size_bytes?: numberImage file size in bytes. Required by agents that advertise a max_file_size_kb constraint.
Optionalpixel_ratio?: numberIntrinsic pixels per logical render pixel (for example 2 for a 600×500 image intended to render at 300×250). Optional because a validator can infer the ratio when the target format declares logical dimensions. When supplied, it MUST agree with both width / logical_width and height / logical_height; it is never a substitute for the intrinsic width and height fields.
Optionalformat?: stringImage file format (jpg, png, gif, webp, etc.)
Optionalalt_text?: stringAlternative text for accessibility
Optionalprovenance?: {Optionaldigital_source_type?: ...Optionalsynthetic_depiction?: ...Assessed declaration of whether the content synthetically depicts a real or fictional person performing or appearing in a way that was generated or materially manipulated rather than captured as depicted. true covers both a fully synthetic performer and material manipulation of a real performer; false is an assessed declaration that the content does not contain such a depiction. Absence means the content has not been assessed for synthetic depiction. This field does not claim consent, legality, or independent verification, and receivers MUST NOT derive it solely from digital_source_type.
Optionalai_tool?: ...AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.
Optionalhuman_oversight?: ...Level of human involvement in the AI-assisted creation process. Independent of disclosure.required — the protocol does not derive disclosure obligations from oversight level. Some regulations include carve-outs for human-edited or human-directed AI output, but those carve-outs have factual prerequisites the schema cannot evaluate. Asserting edited or directed does not by itself justify disclosure.required: false.
Optionaldeclared_by?: ...Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.
Optionaldeclared_at?: ...When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance.
Optionalcreated_time?: ...When this content was created or generated (ISO 8601)
Optionalc2pa?: ...C2PA sidecar manifest reference. Links to a detached cryptographic provenance manifest for this content. Note: file-level C2PA bindings break when ad servers transcode, resize, or re-encode assets. For pipelines with intermediaries, consider embedded_provenance as the primary provenance mechanism.
Optionalembedded_provenance?: ...Provenance metadata embedded within the content stream. Each entry declares one embedding layer: structured provenance data carried inside the content itself, as distinct from sidecar references (c2pa.manifest_url). Embedded provenance survives operations that break sidecar and file-level bindings: ad-server transcoding, CMS ingestion, copy-paste, reformatting, and CDN re-encoding. For ad-tech pipelines where content passes through multiple intermediaries, embedded provenance is the reliable path for provenance that persists from declaration through delivery. This is a declaration by the embedding party. The receiving party (the seller) is the verifier-of-record: it confirms the claim by calling a governance agent it trusts (typically one published in creative_policy.accepted_verifiers).
Optionalwatermarks?: ...Content watermarks applied to this asset. Each entry declares one watermarking layer: a content modification that encodes an identifier or fingerprint within the asset. Watermarks differ from embedded provenance: a watermark encodes an identifier (who generated it, who owns it), while embedded provenance carries or references a structured provenance record (the full chain of custody). A single asset may carry both. Aligns with C2PA action taxonomy: c2pa.watermarked.bound (watermark linked to a C2PA manifest) and c2pa.watermarked.unbound (watermark independent of any manifest). This is a declaration by the watermarking party. The receiving party (the seller) is the verifier-of-record: it confirms the claim by calling a governance agent it trusts (typically one published in creative_policy.accepted_verifiers).
Optionaldisclosure?: ...Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.
Optionalverification?: ...Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim — verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.
Optionalext?: ...Optionalcolors?: { primary?: string; secondary?: string; accent?: string }Override brand colors (hex strings).
Optionalprimary?: stringOptionalsecondary?: stringOptionalaccent?: stringOptionalvoice?: stringOverride brand-voice description for surface-composed text/audio output.
Optionaltagline?: stringOverride tagline.
Optionaloperator?: stringDomain of the entity operating this account. When the brand operates directly, this is the brand's domain.
Optionaloperator_unit?: { id: string; name?: string }Stable identifier assigned by the operator. Numeric platform IDs and durable slugs are both valid. Scoped by the enclosing operator domain.
Optionalname?: stringHuman-readable seat or business-unit name, such as Nova EMEA. This label may change and is not part of the natural account key.
Optionalrevision?: numberMonotonically increasing optimistic-concurrency token for this account. Incremented on every persisted settings change, identity-change request, and identity-change disposition; reads, dry runs, validation failures, and exact idempotency replays do not increment it. Pass the latest observed value in a sync_accounts settings-update entry to prevent lost updates.
Optionalidentity_change?: Optionalcurrency?: stringImmutable transaction currency when the seller's advertiser object is currency-bound. Media buys on this account MUST use this currency. Omit when the account selects currency independently per media buy.
Optionaltimezone?: stringImmutable operational timezone for this account, expressed as UTC or an IANA timezone identifier. AdCP 3.2 sellers return it on every account. It is the default calendar-day boundary for account-scoped behavior unless a feature explicitly declares another timezone basis. For buyer-selected account_fixed provisioning it participates in the natural account key.
Optionalbilling?: BillingPartyOptionalbilling_entity?: Omit<Optionaldestination_billing_entity?: Omit<Omit<{}, "bank">, "authentication"> & { authentication?: unknown }Request-only staging field. It MUST NOT appear in account read models.
Optionalrate_card?: stringIdentifier for the rate card applied to this account
Optionalpayment_terms?: PaymentTermsOptionalcredit_limit?: { amount: number; currency: string }Maximum outstanding balance allowed
Optionalsetup?: { url?: string; message: string; expires_at?: string }Present when status is 'pending_approval'. Contains next steps for completing account activation.
Optionalurl?: stringURL where the human can complete the required action (credit application, legal agreement, add funds).
Human-readable description of what's needed.
Optionalexpires_at?: stringWhen this setup link expires.
Optionalaccount_scope?: AccountScopeOptionalgovernance_agents?: { url: string }[]Governance agent endpoint registered on this account. Exactly one entry per sync_governance's one-agent-per-account invariant. The array shape is preserved for wire compatibility with 3.0; maxItems: 1 is load-bearing and mirrors the singular governance_context on the protocol envelope. Authentication credentials are write-only and not included in responses — use sync_governance to set or update credentials.
Optionalreporting_bucket?: {Cloud storage bucket where the seller delivers offline reporting files for this account. Seller provisions a dedicated bucket or a per-account prefix within a shared bucket, and grants the buyer read access out-of-band. Access MUST be scoped at the IAM layer so each account can only read its own prefix — bucket-wide grants are non-compliant even with per-account prefixes. Seller MUST revoke access when the account's status transitions to inactive, suspended, or closed. See security considerations for offline delivery in docs/media-buy/media-buys/optimization-reporting. Only present when the seller supports offline delivery (reporting_delivery_methods includes 'offline' in capabilities).
Bucket or container name
Optionalprefix?: stringPath prefix within the bucket. Seller appends date-based partitioning beneath this prefix.
Optionalregion?: stringCloud region for the bucket
Optionalformat?: "jsonl" | "csv" | "parquet" | "avro" | "orc"File format for delivered files. Parquet, Avro, and ORC use internal compression (the top-level compression field is ignored for these formats).
Optionalcompression?: "none" | "gzip"Compression applied to delivered files
How long reporting files are retained in the bucket before deletion. Buyers must read files within this window. Minimum recommended: 14 days.
Optionalsetup_instructions?: stringURL to documentation for configuring buyer read access to this bucket (IAM role, service account, etc.). Operator-facing documentation — buyer agents MUST NOT auto-fetch this URL; surface it to a human operator. If an implementation fetches it (for preview), apply webhook URL SSRF validation and do not pass the fetched content into an LLM context without indirect-prompt-injection guarding. See docs/media-buy/media-buys/optimization-reporting#security-considerations-for-offline-delivery.
Optionalsandbox?: booleanWhen true, this is a sandbox account — no real platform calls, no real spend. For account-id namespaces, sandbox accounts are pre-existing test accounts on the platform discovered via list_accounts or supplied out-of-band. For buyer-declared accounts, sandbox is part of the natural key: the same brand/operator pair can have both a production and sandbox account.
Optionalnotification_configs?: Account-level webhook subscriptions for creative lifecycle/assignment changes, indicators.changed, account status, and wholesale feed changes. Buyers manage entries via sync_accounts and verify persisted state on list_accounts. Indicator and assignment payloads are invalidations repaired completely through get_media_buys; list_creatives may provide a bounded reverse projection. Distinct from per-resource push_notification_config. Entries are keyed by account-scoped subscriber_id; credentials are write-only.
Optionalwebhook_activity?: {Recent webhook delivery attempts scoped to this account when the caller requested webhook activity on list_accounts and the seller surfaces the log. Includes account-anchored notifications such as account.status_changed and MAY include other account-level fires relevant to this account. Three-state presence follows the shared webhook_activity[] contract: omitted means unsupported or not requested, [] means supported but no retained fires, non-empty lists recent attempts most-recent-first.
Optionalext?: Omit<Omit<{ [key: string]: unknown }, "bank">, "authentication"> & {Optionalinvoice_recipient?: Omit<Optionalmedia_buy_status?: MediaBuyStatusOptionalconfirmed_at?: string | nullISO 8601 timestamp when this media buy was committed by the seller. Stable after it is set; do not update on later pause/resume/status/reporting transitions. May be null in deferred or manual-approval flows until seller commitment occurs.
Optionalcreative_deadline?: stringISO 8601 timestamp for creative upload deadline
Optionalrevision?: numberInitial revision number for this media buy. Use in subsequent update_media_buy requests intended to change state for optimistic concurrency.
Optionalcurrency?: stringSingle ISO 4217 currency code for total_budget, package budget constraints, and canonical BiddingPolicy monetary fields. Every selected pricing option MUST declare this currency; packages needing another currency belong in another media buy. In proposal mode the seller derives it from total_budget.currency; in explicit-package mode the seller derives or validates one common pricing-option currency. Matches subsequent get_media_buys responses.
Optionaltotal_budget?: numberHard aggregate lifetime budget, denominated in currency. The request encodes total_budget as an object {amount, currency}; this response flattens amount and promotes currency to its sibling field. Present for proposal and seller-optimized modes, and when supplied or deterministically derived in fixed explicit-package mode. Matches subsequent get_media_buys responses.
Optionaldaily_budget_cap?: numberAccepted hard aggregate daily spend ceiling, denominated in currency. Sellers MUST echo it whenever the request set an aggregate daily cap.
Optionalbudget_cap_timezone?: stringAccepted IANA timezone shared by every aggregate and package daily cap. Sellers MUST echo it whenever any daily cap is set on the media buy.
Optionalbudget_allocation?: Accepted cross-package allocation configuration. Omitted means fixed allocation for legacy buys.
Optionalpacing?: PacingOptionalbidding?: {Accepted media-buy-authored bidding policy with goal binding and monetary denomination preserved. Packages that inherit it omit package.bidding; explicit package policies, including {automatic:true}, remain at package scope.
Optionalautomatic?: trueExplicitly use seller/provider automatic bidding at this authored scope. At package scope this is a complete override of a media-buy policy, not inheritance. It MUST be the only field in the block and MUST be preserved on readback.
Optionalbid_amount?: numberManual auction bid denominated in the media-buy currency and expressed per the selected pricing option's auction unit. For example, a CPM option interprets the amount per thousand impressions. This is the amount submitted to the auction, not a promise that the clearing price equals it. Requires an auction-priced pricing option whose currency equals the media-buy currency.
Optionalmax_bid?: numberHard per-auction ceiling denominated in the media-buy currency and expressed per the selected pricing option's auction unit. This is the only canonical hard auction ceiling and MUST NOT be translated into an average outcome-cost control. Requires an auction-priced pricing option whose currency equals the media-buy currency. May stand alone or supplement cost_per/roas only when the relevant scope capability advertises that combination.
Optionalcost_per?: { amount: number; strength: "cap" | "target" }Average cost control per result of the scope-bound primary optimization goal. At seller-optimized media-buy scope it binds to budget_allocation.optimization_goals; at package scope it binds to that package's optimization_goals; at fixed media-buy scope it binds independently to each inheriting package and is valid only when their primary-goal result units are compatible. Metric goals are compatible only when metric and every result-defining qualifier match; vendor_metric goals only when vendor and metric_id match; event goals only when the event_type/custom_event_name set and resolved attribution_window match. Primary is the earliest array entry among goals tied for the lowest explicit numeric priority; unprioritized goals follow explicitly prioritized goals; when all priorities are absent, the first entry is primary.
Average cost amount per scope-bound primary-goal result, denominated in the media-buy currency.
cap optimizes for an average at or below the amount and accepts underdelivery when necessary; target optimizes around the amount while balancing volume and spend. Neither is a per-result or per-auction guarantee.
Optionalroas?: { value: number; strength: "target" | "floor" }Dimensionless return-on-ad-spend control bound to the same scope-specific primary goal rules as cost_per. The bound goal must be value-bearing; a fixed media-buy default requires a value-bearing primary goal on every inheriting package. Every referenced value-bearing event source MUST declare value_currencies containing the media-buy currency. The seller validates this at buy creation; each buy consumes only exact-currency records, while other declared currencies remain available to other buys. Sellers MUST NOT perform currency conversion.
Return per unit of ad spend; 4 means 4 units of value per 1 unit spent.
floor prefers underdelivery to knowingly optimizing below the requested return; target optimizes around the requested return. Neither guarantees realized return.
Optionalvalid_actions?: MediaBuyValidAction[]Flat-vocabulary actions the buyer can perform on this media buy after creation. Saves a round-trip to get_media_buys. Deprecated in favor of available_actions[], which carries mode, optional SLA, and optional terms_ref. Sellers SHOULD populate both during the 3.x deprecation window; consumers MUST prefer available_actions[] when both are present. Removed in 4.0.
Optionalavailable_actions?: {Structured per-buy resolution of actions available immediately after creation. Authoritative — see get-media-buys-response.json for full semantics.
Array of created packages with complete state information
Optionalplanned_delivery?: {Optionalmedia_buy_id?: stringSeller-assigned media buy identifier. Optional on a purchase-phase prepare/check because the service may not assign the identifier until commit; required on modification and delivery lifecycle checks.
Optionalproposal_id?: stringProposal snapshot being executed or currently governing the MediaBuy.
Optionalproposal_terms_digest?: stringDigest of the proposal commercial_terms. The governance agent compares it to the digest bound during the intent check.
Optionalgeo?: { countries?: string[]; regions?: string[] }Geographic targeting the seller will apply.
Optionalcountries?: string[]ISO 3166-1 alpha-2 country codes where ads will deliver.
Optionalregions?: string[]ISO 3166-2 subdivision codes where ads will deliver.
Optionalchannels?: MediaChannel[]Channels the seller will deliver on.
Optionalstart_time?: stringActual flight start the seller will use.
Optionalend_time?: stringActual flight end the seller will use.
Optionalfrequency_cap?: {Optionalsuppress?: {Cooldown period between consecutive exposures to the same entity. Prevents back-to-back ad delivery (e.g. {"interval": 60, "unit": "minutes"} for a 1-hour cooldown). Preferred over suppress_minutes.
Number of time units. Must be 1 when unit is 'campaign'.
Time unit. 'seconds' for sub-minute precision. 'campaign' spans the full campaign flight.
Optionalsuppress_minutes?: numberOptionalmax_impressions?: numberMaximum number of impressions per entity per window. For duration windows, implementations typically use a rolling window; 'campaign' applies a fixed cap across the full flight.
Optionalper?: ReachUnitEntity granularity for impression counting. Required when max_impressions is set.
Optionalwindow?: {Time window for the max_impressions cap (e.g. {"interval": 7, "unit": "days"} or {"interval": 1, "unit": "campaign"} for the full flight). Required when max_impressions is set.
Number of time units. Must be 1 when unit is 'campaign'.
Time unit. 'seconds' for sub-minute precision. 'campaign' spans the full campaign flight.
Optionalaudience_summary?: stringHuman-readable summary of the audience the seller will target.
Optionalaudience_targeting?: (Structured audience targeting the seller will activate. Each entry is either a signal reference or a descriptive criterion. When present, governance agents MUST use this for bias/fairness validation and SHOULD ignore audience_summary for validation purposes. The audience_summary field is a human-readable rendering of this array, not an independent declaration.
Optionaltotal_budget?: numberTotal budget the seller will deliver against.
Optionaldaily_budget_cap?: numberHard aggregate daily spend ceiling the seller will enforce. Governance checks compare it with the authorized execution controls; it does not allocate spend to packages.
Optionalbudget_cap_timezone?: stringIANA timezone defining the calendar-day boundary for every daily cap on the planned media buy.
Optionalcurrency?: stringISO 4217 currency code for the budget. Governance execution checks require it whenever total_budget is present and require it to match the intent-authorized currency.
Optionalbudget_allocation?: Seller-accepted cross-package allocation authority and goals. Presence with seller_optimized mode means automatic within-buy reallocations are part of the committed delivery, not separate modification actions.
Optionalpacing?: PacingOptionalbidding?: {Seller-interpreted media-buy bidding policy used for governance and delivery transparency. Goal-bound controls follow budget-allocation scope semantics and monetary fields use the planned delivery currency. Package-authored overrides, including explicit automatic overrides, remain on packages rather than being copied into this aggregate field.
Optionalautomatic?: trueExplicitly use seller/provider automatic bidding at this authored scope. At package scope this is a complete override of a media-buy policy, not inheritance. It MUST be the only field in the block and MUST be preserved on readback.
Optionalbid_amount?: numberManual auction bid denominated in the media-buy currency and expressed per the selected pricing option's auction unit. For example, a CPM option interprets the amount per thousand impressions. This is the amount submitted to the auction, not a promise that the clearing price equals it. Requires an auction-priced pricing option whose currency equals the media-buy currency.
Optionalmax_bid?: numberHard per-auction ceiling denominated in the media-buy currency and expressed per the selected pricing option's auction unit. This is the only canonical hard auction ceiling and MUST NOT be translated into an average outcome-cost control. Requires an auction-priced pricing option whose currency equals the media-buy currency. May stand alone or supplement cost_per/roas only when the relevant scope capability advertises that combination.
Optionalcost_per?: { amount: number; strength: "cap" | "target" }Average cost control per result of the scope-bound primary optimization goal. At seller-optimized media-buy scope it binds to budget_allocation.optimization_goals; at package scope it binds to that package's optimization_goals; at fixed media-buy scope it binds independently to each inheriting package and is valid only when their primary-goal result units are compatible. Metric goals are compatible only when metric and every result-defining qualifier match; vendor_metric goals only when vendor and metric_id match; event goals only when the event_type/custom_event_name set and resolved attribution_window match. Primary is the earliest array entry among goals tied for the lowest explicit numeric priority; unprioritized goals follow explicitly prioritized goals; when all priorities are absent, the first entry is primary.
Average cost amount per scope-bound primary-goal result, denominated in the media-buy currency.
cap optimizes for an average at or below the amount and accepts underdelivery when necessary; target optimizes around the amount while balancing volume and spend. Neither is a per-result or per-auction guarantee.
Optionalroas?: { value: number; strength: "target" | "floor" }Dimensionless return-on-ad-spend control bound to the same scope-specific primary goal rules as cost_per. The bound goal must be value-bearing; a fixed media-buy default requires a value-bearing primary goal on every inheriting package. Every referenced value-bearing event source MUST declare value_currencies containing the media-buy currency. The seller validates this at buy creation; each buy consumes only exact-currency records, while other declared currencies remain available to other buys. Sellers MUST NOT perform currency conversion.
Return per unit of ad spend; 4 means 4 units of value per 1 unit spent.
floor prefers underdelivery to knowingly optimizing below the requested return; target optimizes around the requested return. Neither guarantees realized return.
Optionalenforced_policies?: string[]Registry policy IDs the seller will enforce for this delivery.
Optionalext?: Omit<Omit<{ [key: string]: unknown }, "bank">, "authentication"> & {Optionalwarnings?: {Optional non-blocking observations accompanying this successful creation. The media buy was still created. Buyers SHOULD surface recognized codes operationally rather than treating this as an error; continuing conditions also appear on get_media_buys as current resource state.
Optionalsandbox?: booleanWhen true, this response contains simulated data from sandbox mode.
Optionalcontext?: Omit<Omit<{}, "bank">, "authentication"> & { authentication?: unknown }Optionalext?: Omit<Omit<{ [key: string]: unknown }, "bank">, "authentication"> & {Optionalsummary: string
The immutable committed proposal executed by this media buy, echoed when proposal_id was supplied in the request.