{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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, and optional warnings[] reports non-blocking observations; (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. A continuing condition first surfaced as a synchronous success warning MUST also appear on its authoritative read surface. These three shapes are mutually exclusive — a response has exactly one.",
  "type": "object",
  "allOf": [
    {
      "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/version-envelope.json"
    },
    {
      "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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"
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255,
          "pattern": "\\S",
          "description": "Persisted human-readable name after the update. When update_media_buy supplied name, the seller MUST return the stored value here; a seller that could not apply the replacement SHOULD return the prior unchanged value rather than silently dropping the field. This display label is not an identifier or financial reference."
        },
        "media_buy_status": {
          "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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'). This field carries the media buy lifecycle state; top-level `status` is reserved for the protocol-envelope TaskStatus."
        },
        "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 hard aggregate lifetime budget, denominated in currency. Echoed when the update affects the shared total or package budgets so buyers can verify the new aggregate without a round-trip to get_media_buys.",
          "minimum": 0
        },
        "daily_budget_cap": {
          "type": "number",
          "description": "Post-update hard aggregate daily spend ceiling. Echoed when the update sets or changes the aggregate daily cap; omitted after the cap is removed.",
          "minimum": 0
        },
        "budget_cap_timezone": {
          "type": "string",
          "description": "Post-update IANA timezone shared by every aggregate and package daily cap. Echoed whenever the update affects daily caps or their timezone."
        },
        "budget_allocation": {
          "allOf": [
            {
              "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/budget-allocation.json"
            }
          ],
          "description": "Post-update cross-package allocation configuration when affected by the update."
        },
        "pacing": {
          "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/enums/pacing.json",
          "description": "Post-update aggregate pacing when affected by the update."
        },
        "bidding": {
          "allOf": [
            {
              "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/bidding-policy.json"
            }
          ],
          "description": "Post-update media-buy-authored bidding policy when affected by the update, preserving explicit automatic mode, scope-specific goal binding, and media-buy-currency denomination. Omitted when the authored media-buy block was cleared."
        },
        "implementation_date": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "ISO 8601 timestamp when changes take effect (null if pending approval)"
        },
        "invoice_recipient": {
          "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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 full Package objects showing complete post-update state for each modified package. This includes every active package whose budget was proportionally changed by a fixed-mode total_budget update. This is a state snapshot, not a sparse delta: sellers MUST NOT return package_id-only stubs. Campaign-level updates that do not modify packages may return an empty array.",
          "items": {
            "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/package.json"
          }
        },
        "valid_actions": {
          "type": "array",
          "deprecated": true,
          "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": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/media-buy-available-action.json"
          },
          "uniqueItems": true
        },
        "warnings": {
          "type": "array",
          "description": "Optional non-blocking observations accompanying this successful update. The requested update was still applied. Continuing conditions also appear on get_media_buys as current resource state.",
          "items": {
            "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/warning.json"
          },
          "uniqueItems": true
        },
        "sandbox": {
          "type": "boolean",
          "description": "When true, this response contains simulated data from sandbox mode."
        },
        "context": {
          "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/error.json"
          },
          "minItems": 1
        },
        "context": {
          "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/ext.json"
        }
      },
      "required": [
        "errors"
      ],
      "additionalProperties": true,
      "not": {
        "anyOf": [
          {
            "required": [
              "media_buy_id"
            ]
          },
          {
            "required": [
              "affected_packages"
            ]
          },
          {
            "required": [
              "sandbox"
            ]
          },
          {
            "required": [
              "warnings"
            ]
          },
          {
            "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 invokes get_task_status with task_id or receives a webhook when the task completes; the updated media buy state lands in the terminal result, 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 get_task_status (or the legacy AdCP tasks/get alias), and that the seller references on push-notification callbacks. This AdCP application-layer handle remains the snake_case task_id in every transport payload and is distinct from any transport-native A2A 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": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/error.json"
          }
        },
        "context": {
          "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/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": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/ext.json"
        }
      },
      "required": [
        "status",
        "task_id"
      ],
      "additionalProperties": true,
      "not": {
        "anyOf": [
          {
            "required": [
              "media_buy_id"
            ]
          },
          {
            "required": [
              "warnings"
            ]
          }
        ]
      }
    }
  ],
  "properties": {}
}
