Skip to main content

report_plan_outcome

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.
Report the outcome of an action to the governance agent. Called by the orchestrator after a seller responds. The report closes the authorization record, but it does not let the caller choose the ledger amount: the governance agent reserves the amount from its own approved check state and retains the seller response for reconciliation and audit. Sellers do not call this task. They report delivery data via check_governance with phase: "delivery".

Seller response (after create_media_buy)

Response (no issues)

The governance agent updates its state from the amount it authorized. For a create, when an online purchase execution check approved a narrower planned_delivery.total_budget, that seller-side checked amount is authoritative; otherwise the approved intent amount remains reserved. For update_media_buy, the intent reserves the buyer-proposed positive-delta ceiling and a successful online execution check may narrow it to the seller-computed execution_commitment; the post-update total is never added again as a fresh commitment. The transport credential must resolve to the same buyer-side agent URL that made the original approved intent check. The governance agent also requires purchase_type to match that intent and allows only one terminal completed or failed settlement across the intent and execution checks sharing the same opaque action binding. Retrying the identical request with the same idempotency_key returns the cached response with replayed: true; reusing the key for a different payload is an idempotency conflict.

Response (discrepancy found)

In this alternative scenario for the same action, the seller modified the request:
The caller’s lower report is preserved in the audit trail but cannot manufacture plan headroom. If the seller prepared a $120K delivery and obtained a purchase execution approval for it before commit, that governance-owned execution record becomes authoritative and the ledger reserves $120K. All monetary inputs MUST be finite and non-negative. Invalid or overflowing values are rejected before ledger or audit mutation. Each approved check may be settled by only one completed or failed outcome; idempotent replay returns the cached result, while a second distinct settlement is a conflict.

Buyer delivery observation

The seller first submits a canonical delivery statement through check_governance with phase: "delivery". The buyer then binds its observation to that exact approved seller check. This preserves two attributed records instead of treating either party as the universal source of truth.
Use source: "seller_statement_copy" when the buyer is forwarding the statement it received from the seller. That proves consistent transmission, not independent measurement. Use source: "buyer_measurement" for separately measured buyer evidence; seller statement ID and digest are then optional. Delivery observations never add spend to the already-recorded commitment. Authoritative seller monitoring uses check_governance with phase: "delivery"; the buyer observation remains separately attributed audit evidence.

Response (on track)

Response (forwarded seller copy does not match the canonical statement)

A seller_statement_copy whose statement ID or digest differs from what the seller filed with governance means the seller told two different stories. This is a dispute, and it blocks adjustment acceptance while the period is open:
A forwarded copy whose digest matches the canonical statement but whose values differ is internally inconsistent — the digest covers the period, spend, and currency — and is rejected as a VALIDATION_ERROR rather than recorded as a dispute.

Response (buyer measurement differs from the seller statement)

A buyer_measurement with a matching period and currency but a different cumulative_spend is expected measurement noise, not equivocation. It is recorded, attributed, and non-blocking:
A buyer_measurement whose reporting period or currency differs from the canonical statement is not comparable and produces disputed, as for a mismatched forwarded copy. In every disagreement, governance retains both attributed amounts and reports max(seller_reported_spend, buyer_observed_spend) as conservative exposure in get_plan_audit_logs. The same conservative figure bounds verified decommitments, so neither side gains anything from manufacturing a disagreement. Only a disputed state blocks adjustment acceptance; measurement_variance never does. Governance never averages the claims or applies a last-writer-wins rule.

Closing an unresolved governance period

The plan owner may submit a new observation for the same seller statement and reporting_period with period_closed: true. Only the authenticated plan owner can close a period; the governance agent rejects period_closed: true from any other authenticated reporter. If the values still disagree, the response makes the limited operational meaning explicit:
Closure freezes that period’s governance evidence and prevents the old discrepancy from blocking later governance or a buyer-reviewed adjustment. It does not determine the final invoice, payable amount, credit balance, or commercial winner. A different subsequent seller reporting period starts open and unmatched; neither party may rewrite the closed period.

Failed actions

If the seller rejected the request, report it so the governance agent can update plan state:

Fields

Request

Response

Error codes