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.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:
- 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. - 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 onlyregions: ["US-MA"]is subject to Massachusetts-specific and federal policies.
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.
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
amountbelow what is already committed to that period.
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 theplan_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 theaudience 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:
check_governance. Signal references enable structural matching; descriptions require semantic comparison.
Restricted attributes
Therestricted_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
Thepolicy_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
Related tasks
check_governance— Validate actions against this planreport_plan_outcome— Report outcomes back to update plan stateget_plan_audit_logs— View plan state and audit trail