{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "/schemas/3.1.0-rc.4/media-buy/update-media-buy-response.json",
  "title": "Update Media Buy Response",
  "description": "Response payload for update_media_buy task. Exactly one of three shapes: (1) synchronous success — media_buy_id and updated state are issued in-line; (2) terminal failure — an errors array with no changes applied; (3) submitted task envelope — status 'submitted' with task_id when the update is queued for async processing (e.g., awaiting operator re-approval for mid-flight changes). The submitted branch MAY carry advisory errors for non-blocking warnings; terminal failures belong in the error branch. These three shapes are mutually exclusive — a response has exactly one.",
  "type": "object",
  "allOf": [
    {
      "$ref": "/schemas/3.1.0-rc.4/core/version-envelope.json"
    },
    {
      "$ref": "/schemas/3.1.0-rc.4/core/protocol-envelope.json"
    }
  ],
  "oneOf": [
    {
      "title": "UpdateMediaBuySuccess",
      "description": "Success response - media buy updated successfully",
      "type": "object",
      "properties": {
        "media_buy_id": {
          "type": "string",
          "description": "Seller's identifier for the media buy",
          "x-entity": "media_buy"
        },
        "media_buy_status": {
          "$ref": "/schemas/3.1.0-rc.4/enums/media-buy-status.json",
          "description": "Media buy status after the update. Present when the update changes the media buy's status (e.g., cancellation transitions to 'canceled', pause transitions to 'paused'). Added in 3.1: at the top level of flat-on-the-wire MCP responses, the `status` key is reserved for the envelope TaskStatus. Sellers SHOULD emit `media_buy_status` from 3.1 onward; the legacy top-level `status: MediaBuyStatus` form is deprecated and removed in 3.2 (#4906). When the deprecated `status` is also present during the 3.1 deprecation window, both MUST carry identical values — divergent emission is a conformance violation flagged by 3.1 compliance storyboards."
        },
        "status": {
          "$ref": "/schemas/3.1.0-rc.4/enums/media-buy-status.json",
          "deprecated": true,
          "description": "DEPRECATED in 3.1, removed in 3.2 (#4906). Use `media_buy_status` instead. During the 3.1 deprecation window, sellers emitting both `status` and `media_buy_status` MUST emit identical values — divergent emission is a conformance violation. See adcontextprotocol/adcp#4895."
        },
        "revision": {
          "type": "integer",
          "description": "Revision number after this update. Use this value in subsequent update_media_buy requests intended to change state for optimistic concurrency. Exact idempotency replays return the prior revision and do not increment revision.",
          "minimum": 1
        },
        "currency": {
          "type": "string",
          "description": "ISO 4217 currency code for monetary values at this media buy level. Echoed when the update affects budget or currency. Matches the currency field in subsequent get_media_buys responses.",
          "pattern": "^[A-Z]{3}$"
        },
        "total_budget": {
          "type": "number",
          "description": "Updated total budget amount across all packages, denominated in currency. Echoed when the update affects package budgets so buyers can verify the new aggregate without a round-trip to get_media_buys. Matches the total_budget field in subsequent get_media_buys responses.",
          "minimum": 0
        },
        "implementation_date": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "ISO 8601 timestamp when changes take effect (null if pending approval)"
        },
        "invoice_recipient": {
          "$ref": "/schemas/3.1.0-rc.4/core/business-entity.json",
          "description": "Updated invoice recipient, echoed from the request when provided. Confirms the seller accepted the billing override. Bank details are omitted (write-only)."
        },
        "affected_packages": {
          "type": "array",
          "description": "Array of packages that were modified with complete state information",
          "items": {
            "$ref": "/schemas/3.1.0-rc.4/core/package.json"
          }
        },
        "valid_actions": {
          "type": "array",
          "description": "Flat-vocabulary actions the buyer can perform after this update. 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.",
          "items": {
            "$ref": "/schemas/3.1.0-rc.4/enums/media-buy-valid-action.json"
          }
        },
        "available_actions": {
          "type": "array",
          "description": "Structured per-buy resolution of actions available after this update. Authoritative — see `get-media-buys-response.json` for full semantics.",
          "items": {
            "$ref": "/schemas/3.1.0-rc.4/core/media-buy-available-action.json"
          },
          "uniqueItems": true
        },
        "sandbox": {
          "type": "boolean",
          "description": "When true, this response contains simulated data from sandbox mode."
        },
        "context": {
          "$ref": "/schemas/3.1.0-rc.4/core/context.json",
          "description": "Opaque operation-level correlation data echoed unchanged from the update_media_buy request. Sellers MUST echo this object verbatim when the originating request carried context, including synchronous success, error, submitted, and webhook task-status payloads. Sellers MUST NOT parse this object for business logic."
        },
        "ext": {
          "$ref": "/schemas/3.1.0-rc.4/core/ext.json"
        }
      },
      "required": [
        "media_buy_id",
        "revision"
      ],
      "additionalProperties": true,
      "not": {
        "required": [
          "errors"
        ]
      }
    },
    {
      "title": "UpdateMediaBuyError",
      "description": "Error response - operation failed, no changes applied",
      "type": "object",
      "properties": {
        "errors": {
          "type": "array",
          "description": "Array of errors explaining why the operation failed",
          "items": {
            "$ref": "/schemas/3.1.0-rc.4/core/error.json"
          },
          "minItems": 1
        },
        "context": {
          "$ref": "/schemas/3.1.0-rc.4/core/context.json",
          "description": "Opaque operation-level correlation data echoed unchanged from the update_media_buy request. Sellers MUST echo this object verbatim when the originating request carried context, including synchronous success, error, submitted, and webhook task-status payloads. Sellers MUST NOT parse this object for business logic."
        },
        "ext": {
          "$ref": "/schemas/3.1.0-rc.4/core/ext.json"
        }
      },
      "required": [
        "errors"
      ],
      "additionalProperties": true,
      "not": {
        "anyOf": [
          {
            "required": [
              "media_buy_id"
            ]
          },
          {
            "required": [
              "affected_packages"
            ]
          },
          {
            "required": [
              "sandbox"
            ]
          },
          {
            "properties": {
              "status": {
                "const": "submitted"
              }
            },
            "required": [
              "status"
            ]
          }
        ]
      }
    },
    {
      "title": "UpdateMediaBuySubmitted",
      "description": "Async task envelope returned when update_media_buy cannot be confirmed before the response — for example, when operator re-approval is required for mid-flight changes. The buyer polls tasks/get with task_id or receives a webhook when the task completes; the updated media buy state lands on the completion artifact, not this envelope.",
      "type": "object",
      "properties": {
        "status": {
          "type": "string",
          "const": "submitted",
          "description": "Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose media_buy_id is issued in-line. See task-status.json for the full task-status enum."
        },
        "task_id": {
          "type": "string",
          "description": "Task handle the buyer uses with tasks/get, and that the seller references on push-notification callbacks. Per AdCP wire conventions this is snake_case; A2A adapters MAY surface it as taskId, but the payload field emitted by the agent is task_id.",
          "x-entity": "task"
        },
        "message": {
          "type": "string",
          "maxLength": 2000,
          "description": "Optional human-readable explanation of why the task is submitted — e.g., 'Awaiting operator re-approval; typical turnaround 2–4 hours.' Plain text only. Buyers MUST treat this as untrusted seller input: escape before rendering to HTML UIs, and sanitize or isolate before passing to an LLM prompt context — a hostile seller may inject prompt-injection payloads aimed at the buyer's agent."
        },
        "errors": {
          "type": "array",
          "description": "Optional advisory errors accompanying the submitted envelope. Use only for non-blocking warnings (e.g., throttled_severity advisories, governance observations). Terminal failures belong in the error branch, not here.",
          "items": {
            "$ref": "/schemas/3.1.0-rc.4/core/error.json"
          }
        },
        "context": {
          "$ref": "/schemas/3.1.0-rc.4/core/context.json",
          "description": "Opaque operation-level correlation data echoed unchanged from the update_media_buy request. Sellers MUST echo this object verbatim when the originating request carried context, including synchronous success, error, submitted, and webhook task-status payloads. Sellers MUST NOT parse this object for business logic."
        },
        "ext": {
          "$ref": "/schemas/3.1.0-rc.4/core/ext.json"
        }
      },
      "required": [
        "status",
        "task_id"
      ],
      "additionalProperties": true,
      "not": {
        "required": [
          "media_buy_id"
        ]
      }
    }
  ],
  "properties": {}
}
