> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# report_plan_outcome

> report_plan_outcome sends action results to the AdCP governance agent so it can update budget tracking, state, and compliance records.

# report\_plan\_outcome

<Note>
  **Experimental.** Campaign governance ([`sync_plans`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/sync_plans), [`check_governance`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/check_governance), `report_plan_outcome`, [`get_plan_audit_logs`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/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](/dist/docs/3.2.0-beta.0/reference/experimental-status) for the full contract.
</Note>

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`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/check_governance) with `phase: "delivery"`.

## Seller response (after `create_media_buy`)

```json theme={null}
{
  "tool": "report_plan_outcome",
  "arguments": {
    "plan_id": "plan_q1_2026_launch",
    "check_id": "chk_xyz789",
    "idempotency_key": "outcome-create-2026-001",
    "governance_context": "gc_mb_seller_456",
    "outcome": "completed",
    "seller_response": {
      "seller_reference": "mb_seller_456",
      "packages": [
        {
          "package_id": "pkg_001",
          "product_id": "premium_video_300k",
          "budget": 150000,
          "targeting_overlay": {
            "geo": { "include": [{ "type": "country", "code": "US" }] },
            "viewability": { "standard": "mrc", "threshold": 50 }
          }
        }
      ],
      "planned_delivery": {
        "geo": { "countries": ["US"] },
        "channels": ["olv"],
        "start_time": "2026-03-15T00:00:00Z",
        "end_time": "2026-06-15T00:00:00Z",
        "total_budget": 150000,
        "currency": "USD"
      },
      "creative_deadline": "2026-03-20T00:00:00Z"
    }
  }
}
```

### Response (no issues)

```json theme={null}
{
  "outcome_id": "out_001",
  "outcome_state": "accepted",
  "committed_budget": 150000,
  "plan_summary": {
    "total_committed": 425000,
    "budget_remaining": 75000
  }
}
```

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`](/dist/docs/3.2.0-beta.0/media-buy/task-reference/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:

```json theme={null}
{
  "outcome_id": "out_002",
  "outcome_state": "findings",
  "committed_budget": 150000,
  "findings": [
    {
      "category_id": "outcome_budget_reconciliation",
      "severity": "warning",
      "explanation": "Caller reported $120,000; ledger reserved the governance-authorized $150,000. A seller-side purchase execution check is required to narrow the authoritative amount.",
      "details": {
        "discrepancies": [
          { "field": "packages[0].budget", "requested": 150000, "received": 120000 },
          { "field": "packages[0].targeting_overlay.geo.include", "requested": ["US"], "received": ["US", "CA"] }
        ]
      }
    }
  ],
  "plan_summary": {
    "total_committed": 425000,
    "budget_remaining": 75000
  }
}
```

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`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/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.

```json theme={null}
{
  "tool": "report_plan_outcome",
  "arguments": {
    "plan_id": "plan_q1_2026_launch",
    "check_id": "chk_seller_delivery_001",
    "idempotency_key": "outcome-delivery-2026-001",
    "governance_context": "gc_mb_seller_456",
    "outcome": "delivery",
    "delivery": {
      "observation_id": "obs_q1_launch_001",
      "source": "seller_statement_copy",
      "observed_at": "2026-03-22T01:05:00Z",
      "reporting_period": {
        "start": "2026-03-15T00:00:00Z",
        "end": "2026-03-22T00:00:00Z"
      },
      "cumulative_spend": 12500,
      "currency": "USD",
      "seller_statement_id": "stmt_q1_launch_001",
      "seller_statement_digest": "sha256:4b55f1157094ed8df2635250f71568701d294cb0da57845eba886a62e5434633",
      "impressions": 850000
    }
  }
}
```

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`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/check_governance) with `phase: "delivery"`; the buyer observation remains separately attributed audit evidence.

### Response (on track)

```json theme={null}
{
  "outcome_id": "out_del_001",
  "outcome_state": "accepted",
  "delivery_reconciliation_status": "consistent",
  "delivery_period_state": "open"
}
```

### 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:

```json theme={null}
{
  "outcome_id": "out_del_002",
  "outcome_state": "findings",
  "delivery_reconciliation_status": "disputed",
  "delivery_period_state": "open",
  "findings": [
    {
      "category_id": "delivery_evidence_conflict",
      "severity": "critical",
      "explanation": "The forwarded seller statement does not match the canonical statement retained by governance.",
      "details": {
        "field": "delivery.seller_statement_digest",
        "expected": "sha256:4b55f1157094ed8df2635250f71568701d294cb0da57845eba886a62e5434633",
        "actual": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
      }
    }
  ]
}
```

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`](/dist/docs/3.2.0-beta.0/building/verification/compliance-catalog#error-code-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:

```json theme={null}
{
  "outcome_id": "out_del_004",
  "outcome_state": "findings",
  "delivery_reconciliation_status": "measurement_variance",
  "delivery_period_state": "open",
  "findings": [
    {
      "category_id": "delivery_measurement_variance",
      "severity": "warning",
      "explanation": "Buyer-measured delivery differs from the seller statement; the higher amount is used as conservative exposure and as the delivered figure for decommitment bounds.",
      "details": {
        "field": "delivery.cumulative_spend",
        "seller_stated": 12500,
        "buyer_observed": 12384
      }
    }
  ]
}
```

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`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/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:

```json theme={null}
{
  "outcome_id": "out_del_003",
  "outcome_state": "findings",
  "delivery_reconciliation_status": "closed_unresolved",
  "delivery_period_state": "closed"
}
```

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:

```json theme={null}
{
  "tool": "report_plan_outcome",
  "arguments": {
    "plan_id": "plan_q1_2026_launch",
    "check_id": "chk_xyz789",
    "idempotency_key": "outcome-failed-2026-001",
    "governance_context": "gc_mb_seller_456",
    "outcome": "failed",
    "error": {
      "code": "PRODUCT_UNAVAILABLE",
      "message": "Product premium_video_300k is no longer available."
    }
  }
}
```

```json theme={null}
{
  "outcome_id": "out_003",
  "outcome_state": "accepted",
  "committed_budget": 0,
  "plan_summary": {
    "total_committed": 275000,
    "budget_remaining": 225000
  }
}
```

## Fields

### Request

| Field                               | Type      | Required        | Description                                                                                                                                                                                                                                                                   |
| ----------------------------------- | --------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plan_id`                           | string    | Yes             | The plan this outcome is for.                                                                                                                                                                                                                                                 |
| `check_id`                          | string    | Conditional     | Exact approved check. Required for every outcome; a delivery observation names the seller delivery statement check.                                                                                                                                                           |
| `idempotency_key`                   | string    | Yes             | Stable retry key. An identical replay returns the cached outcome without another ledger mutation; reuse with a different payload is rejected.                                                                                                                                 |
| `purchase_type`                     | enum      | No              | The kind of financial commitment: `media_buy` (default), `rights_license`, `signal_activation`, or `creative_services`. When omitted, the governance agent assumes `media_buy`.                                                                                               |
| `outcome`                           | enum      | Yes             | `completed`, `failed`, or `delivery`.                                                                                                                                                                                                                                         |
| `seller_response`                   | object    | No              | The seller's full response. Required when outcome is `completed`.                                                                                                                                                                                                             |
| `seller_response.seller_reference`  | string    | No              | The seller's identifier for the created resource (e.g., `media_buy_id`, `rights_grant_id`, `deployment_id`). Not interpreted by the governance agent — included in audit logs for human-readable traceability alongside the opaque `governance_context`.                      |
| `seller_response.committed_budget`  | number    | No              | Buyer-reported seller amount retained for reconciliation. Never ledger authority. A value above the approved amount is rejected; a lower value does not restore headroom.                                                                                                     |
| `seller_response.packages`          | array     | No              | Confirmed packages with actual budget and targeting.                                                                                                                                                                                                                          |
| `seller_response.planned_delivery`  | object    | No              | What the seller said it will deliver. When seller-side governance is not configured, this is the governance agent's only view of the seller's delivery parameters.                                                                                                            |
| `seller_response.creative_deadline` | string    | No              | ISO 8601 deadline for creative submission.                                                                                                                                                                                                                                    |
| `delivery`                          | object    | No              | Buyer-attributed observation. Required for `delivery`; retained separately from the seller statement and never added as a second commitment.                                                                                                                                  |
| `delivery.observation_id`           | string    | For delivery    | Stable buyer-issued record ID.                                                                                                                                                                                                                                                |
| `delivery.source`                   | enum      | For delivery    | `seller_statement_copy` or `buyer_measurement`.                                                                                                                                                                                                                               |
| `delivery.observed_at`              | date-time | For delivery    | When the buyer recorded the observation.                                                                                                                                                                                                                                      |
| `delivery.reporting_period`         | object    | For delivery    | Exact period compared with the seller statement.                                                                                                                                                                                                                              |
| `delivery.cumulative_spend`         | number    | For delivery    | Finite, non-negative buyer-attributed cumulative spend.                                                                                                                                                                                                                       |
| `delivery.currency`                 | string    | For delivery    | Three-letter currency matching the compared evidence.                                                                                                                                                                                                                         |
| `delivery.period_closed`            | boolean   | No              | Defaults to `false`. Only the authenticated plan owner may close this operational governance period; the governance agent rejects the value from any other authenticated reporter. An unresolved close is retained as `closed_unresolved`; closure is not billing settlement. |
| `delivery.seller_statement_id`      | string    | For seller copy | ID received with the seller statement.                                                                                                                                                                                                                                        |
| `delivery.seller_statement_digest`  | string    | For seller copy | Digest received with the seller statement.                                                                                                                                                                                                                                    |
| `delivery.impressions`              | integer   | No              | Optional buyer-attributed impressions.                                                                                                                                                                                                                                        |
| `error`                             | object    | No              | Error details. Required when outcome is `failed`.                                                                                                                                                                                                                             |
| `error.code`                        | string    | No              | Error code from the seller.                                                                                                                                                                                                                                                   |
| `error.message`                     | string    | No              | Human-readable error description.                                                                                                                                                                                                                                             |
| `governance_context`                | string    | Conditional     | Exact approved context paired with `check_id` and `plan_id`. Required for every outcome.                                                                                                                                                                                      |

### Response

| Field                            | Type   | Description                                                                                                                                                             |
| -------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `outcome_id`                     | string | Unique identifier for this outcome record.                                                                                                                              |
| `outcome_state`                  | enum   | `accepted` (state updated, no issues) or `findings` (issues detected).                                                                                                  |
| `committed_budget`               | number | Governance-authorized budget reserved by this completed outcome.                                                                                                        |
| `delivery_reconciliation_status` | enum   | `consistent`, `measurement_variance`, `disputed`, `unmatched`, or `closed_unresolved`; present for delivery observations. Only `disputed` blocks adjustment acceptance. |
| `delivery_period_state`          | enum   | `open` or `closed`. Closure freezes governance evidence but does not settle billing.                                                                                    |
| `findings`                       | array  | Present only when `outcome_state` is `findings`.                                                                                                                        |
| `findings[].category_id`         | string | Which validation category flagged the issue.                                                                                                                            |
| `findings[].severity`            | enum   | `info`, `warning`, or `critical`.                                                                                                                                       |
| `findings[].explanation`         | string | Human-readable description of the issue.                                                                                                                                |
| `findings[].details`             | object | Structured details for programmatic consumption.                                                                                                                        |
| `plan_summary`                   | object | Updated plan budget state (present for `completed`/`failed` outcomes).                                                                                                  |

## Error codes

| Code                                                                                                                       | Recovery    | Description                                                                                                                                                                                                                                 |
| -------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`REFERENCE_NOT_FOUND`](/dist/docs/3.2.0-beta.0/building/verification/compliance-catalog#error-code-reference-not-found)   | correctable | `plan_id` or `check_id` does not resolve within the authenticated reporter's scope. Verify the identifiers and authenticated buyer; do not probe another buyer's plan.                                                                      |
| [`VALIDATION_ERROR`](/dist/docs/3.2.0-beta.0/building/verification/compliance-catalog#error-code-validation-error)         | correctable | The exact tuple, purchase type, outcome-dependent fields, idempotency-key format, or monetary evidence is invalid. Correct the named value; delivery observations must bind both `check_id` and `governance_context` to a seller statement. |
| [`IDEMPOTENCY_CONFLICT`](/dist/docs/3.2.0-beta.0/building/verification/compliance-catalog#error-code-idempotency-conflict) | correctable | This reporter already used the key with another canonical payload. Resend the exact original request for replay, or use a fresh key for a genuinely distinct report.                                                                        |
| [`PERMISSION_DENIED`](/dist/docs/3.2.0-beta.0/building/verification/compliance-catalog#error-code-permission-denied)       | correctable | The authenticated reporter is not the buyer that owns the plan or made the original approved intent. Retry only with that buyer identity.                                                                                                   |
| [`CONFLICT`](/dist/docs/3.2.0-beta.0/building/verification/compliance-catalog#error-code-conflict)                         | transient   | The opaque governed action already has a different terminal settlement. Read the audit trail and accept the existing settlement; do not retry as a second terminal outcome.                                                                 |
| [`CAMPAIGN_SUSPENDED`](/dist/docs/3.2.0-beta.0/building/verification/compliance-catalog#error-code-campaign-suspended)     | transient   | Plan outcome reporting is paused pending human review. Wait for resolution and contact the plan operator if the suspension persists.                                                                                                        |

## Related tasks

* [`check_governance`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/check_governance) -- The governance check that authorized the action
* [`report_plan_adjustment`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/report_plan_adjustment) -- Append a later seller-authenticated adjustment to a completed outcome
* [`sync_plans`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/sync_plans) -- Push or update the plan
* [`get_plan_audit_logs`](/dist/docs/3.2.0-beta.0/governance/campaign/tasks/get_plan_audit_logs) -- View plan state and audit trail
