Skip to main content

sync_plans

Experimental. Campaign governance (sync_plans, check_governance, report_plan_outcome, get_plan_audit_logs) is part of AdCP 3.0 as an experimental surface — it may change between 3.x releases with at least 6 weeks’ notice. Sellers implementing it MUST declare governance.campaign in experimental_features. See experimental status for the full contract.
Push campaign plans to the governance agent. A plan defines the authorized parameters for a campaign — budget limits, channels, flight dates, authorized markets, and compliance policies — and serves as the source of truth for all validation.

Request

Response

How it works

Plans originate in external systems — an agency’s planning tool, a brand’s budget system, an insertion order. sync_plans pushes them to the governance agent so it knows what to validate against. Syncing a plan that already exists (same plan_id) updates it. The governance agent increments the version and re-evaluates any active campaigns against the updated rules. This handles mid-flight amendments like budget increases or channel additions. Content-standards configurations are separate resources, and their wire contract does not define how running media buys adopt later updates; see updating content-standards policies. Multiple campaigns (identified by governance_context in check_governance and report_plan_outcome) can reference the same plan. The governance agent tracks budget across all campaigns tied to a plan. The plan specifies campaign context — budget, channels, flight dates, and authorized markets. The governance agent resolves applicable policies from the brand’s compliance configuration, but plans can also reference registry policies directly via policy_ids and include campaign-specific rules via custom_policies. This supports both centralized policy management (brand-level) and campaign-specific overrides when the buying team needs additional requirements for a particular campaign. countries and regions serve two purposes:
  1. Geo enforcement — The governance agent rejects governed actions targeting outside the plan’s markets. A plan with regions: ["US-MA"] blocks actions that don’t explicitly target Massachusetts.
  2. Policy resolution — The agent finds all policies whose jurisdictions overlap with the plan’s markets. A plan with countries: ["US"] is subject to all US federal and state-level policies. A plan with only regions: ["US-MA"] is subject to Massachusetts-specific and federal policies.
These fields use the same ISO codes and semantics as product-filters, offerings, and create_media_buy — ensuring consistent geo vocabulary across the protocol. A pharma campaign running nationally uses countries: ["US"]; a cannabis campaign limited to legal states uses regions: ["US-CO", "US-CA", "US-MA"].

Budget periods

budget.allocations partitions a plan’s budget by purchase type; budget.periods partitions it by time. Use periods when a campaign budget is split across windows: monthly or quarterly flights, a launch burst followed by a sustain phase, or money that has to be spent before a fiscal quarter closes. Without them, the governance agent can confirm that a buy sits inside the plan flight and that total commitments stay under budget.total, but it cannot stop a buy from spending Q2 money in Q1.
The buyer never names a period when it buys. The governance agent derives the period from the dates of the action being checked; see Budget periods on check_governance. Sellers see nothing new: create_media_buy and every other seller-facing task are unchanged, and the seller receives an ordinary media buy whose dates happen to fit one window. Windows. A period runs from start up to but not including end. Periods MUST sit inside the plan flight and MUST NOT overlap. Adjacent periods MAY share a boundary: delivery at that instant belongs to the later period, so q1 above covers 31 March and q2 begins at midnight on 1 April. budget_period_id MUST be unique within the plan and SHOULD stay stable across syncs, because buyers record it against each buy. Money. amount is denominated in budget.currency. Period amounts MUST sum to at most budget.total. Any remainder is unallocated: it cannot be committed to a dated action until the buyer assigns it to a period by syncing the plan again. The existing budget.total and budget.allocations limits still apply to every commitment, so a dated commitment has to fit both its period and its purchase-type allocation. Undated commitments. Periods govern commitments that carry a flight. A commitment without dates counts against budget.total and its purchase-type allocation only, as it does for a plan without periods, and it never consumes a period’s amount. Re-sync. Syncing a plan again replaces its periods. The governance agent MUST reject the sync with VALIDATION_ERROR when it:
  • leaves an existing dated commitment outside every period, including a commitment whose flight would now straddle a boundary, or
  • sets a period’s amount below what is already committed to that period.
This is the same VALIDATION_ERROR used when budget.total drops below committed spend, and error.field identifies the offending budget.periods entry. A rejected sync leaves the plan unchanged. Periods can be added, extended, or have money moved between them, as long as every existing commitment still sits inside a period with room for it. This applies on the first sync that adds periods to a plan that already has buys: the governance agent applies the same two checks to the dated commitments it already retained. To stop new spending in a period, set its amount to what is already committed. Omitting budget.periods on a re-sync removes period enforcement and returns the plan to total-only governance. A plan without budget.periods behaves exactly as before, which is the same as one period covering the whole flight with the whole budget. Governance agents that enforce periods declare governance.supports_budget_periods; a buyer SHOULD NOT send budget.periods to an agent that does not, because an agent that ignores the field cannot honor a time-partitioned budget. Automatic reallocation between periods, splitting a live buy at a period boundary, and seller-reported delivery broken out by period are out of scope.

Plan-hash preimage

Each plan item a buyer supplies here is the preimage the governance agent hashes to produce the plan_hash audit-layer claim carried in every signed governance_context. Canonicalization rules, the closed bookkeeping exclusion list, retention obligations, and the full set of reference test vectors are specified in Plan binding and audit. Governance-agent implementers SHOULD run their hashing code against the eleven vectors under static/compliance/source/test-vectors/plan-hash/ before shipping.

Fields

Request

Response

Audience constraints

Plans can declare audience targeting constraints using the audience field. Each constraint is an audience selector — either a reference to a specific signal or a natural language description. Signal reference — points to a specific signal in a data provider’s published signal definitions:
Description — natural language for constraints that don’t map to a specific signal:
The governance agent evaluates seller targeting against these constraints during check_governance. Signal references enable structural matching; descriptions require semantic comparison.

Restricted attributes

The restricted_attributes field declares personal data categories that must not be used for targeting. Values are GDPR Article 9 special categories: racial_ethnic_origin, political_opinions, religious_beliefs, trade_union_membership, health_data, sex_life_sexual_orientation, genetic_data, biometric_data. The governance agent matches these against signal definitions that declare their own restricted_attributes. Signals with matching attributes are blocked from targeting. For signals without declared attributes, the governance agent falls back to semantic inference from the signal name and description.

Policy categories

The policy_categories field declares which regulatory regimes apply. Categories are defined in the policy registry and group related regulations — for example, children_directed covers COPPA, UK AADC, and GDPR Article 8. Policy categories are distinct from brand.industries. Industries describe what a company does; policy categories describe what regulatory regimes apply to a specific campaign. A pharmaceutical company (industries: ["pharmaceuticals"]) running a general awareness campaign might not need pharmaceutical_advertising as a policy category if the campaign doesn’t promote specific drugs.

Error codes