{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "/schemas/3.0.0/creative/sync-creatives-request.json",
  "title": "Sync Creatives Request",
  "description": "Request parameters for syncing creative assets with upsert semantics - supports bulk operations, scoped updates, and assignment management",
  "x-mutates-state": true,
  "type": "object",
  "properties": {
    "adcp_major_version": {
      "type": "integer",
      "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.",
      "minimum": 1,
      "maximum": 99
    },
    "account": {
      "$ref": "/schemas/3.0.0/core/account-ref.json",
      "description": "Account that owns these creatives."
    },
    "creatives": {
      "type": "array",
      "description": "Array of creative assets to sync (create or update)",
      "items": {
        "$ref": "/schemas/3.0.0/core/creative-asset.json"
      },
      "minItems": 1,
      "maxItems": 100
    },
    "creative_ids": {
      "type": "array",
      "description": "Optional filter to limit sync scope to specific creative IDs. When provided, only these creatives will be created/updated. Other creatives in the library are unaffected. Useful for partial updates and error recovery.",
      "items": {
        "type": "string",
        "x-entity": "creative"
      },
      "minItems": 1,
      "maxItems": 100
    },
    "assignments": {
      "type": "array",
      "description": "Optional bulk assignment of creatives to packages. Each entry maps one creative to one package with optional weight and placement targeting. Standalone creative agents that do not manage media buys ignore this field.",
      "items": {
        "type": "object",
        "properties": {
          "creative_id": {
            "type": "string",
            "description": "ID of the creative to assign",
            "x-entity": "creative"
          },
          "package_id": {
            "type": "string",
            "description": "ID of the package to assign the creative to",
            "x-entity": "package"
          },
          "weight": {
            "type": "number",
            "description": "Relative delivery weight (0-100). When multiple creatives are assigned to the same package, weights determine impression distribution proportionally. When omitted, the creative receives equal rotation with other unweighted creatives. A weight of 0 means the creative is assigned but paused (receives no delivery).",
            "minimum": 0,
            "maximum": 100
          },
          "placement_ids": {
            "type": "array",
            "description": "Restrict this creative to specific placements within the package. When omitted, the creative is eligible for all placements.",
            "items": {
              "type": "string"
            },
            "minItems": 1
          }
        },
        "required": [
          "creative_id",
          "package_id"
        ],
        "additionalProperties": false
      },
      "minItems": 1
    },
    "idempotency_key": {
      "type": "string",
      "description": "Client-generated idempotency key for safe retries. If a sync fails without a response, resending with the same idempotency_key guarantees at-most-once execution. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.",
      "minLength": 16,
      "maxLength": 255,
      "pattern": "^[A-Za-z0-9_.:-]{16,255}$"
    },
    "delete_missing": {
      "type": "boolean",
      "default": false,
      "description": "When true, creatives not included in this sync will be archived. Use with caution for full library replacement. Invalid when creative_ids is provided — delete_missing applies to the entire library scope, not a filtered subset."
    },
    "dry_run": {
      "type": "boolean",
      "default": false,
      "description": "When true, preview changes without applying them. Returns what would be created/updated/deleted."
    },
    "validation_mode": {
      "$ref": "/schemas/3.0.0/enums/validation-mode.json",
      "default": "strict",
      "description": "Validation strictness. 'strict' fails entire sync on any validation error. 'lenient' processes valid creatives and reports errors."
    },
    "push_notification_config": {
      "$ref": "/schemas/3.0.0/core/push-notification-config.json",
      "description": "Optional webhook configuration for async sync notifications. The agent will send a webhook when sync completes if the operation takes longer than immediate response time (typically for large bulk operations or manual approval/HITL)."
    },
    "context": {
      "$ref": "/schemas/3.0.0/core/context.json"
    },
    "ext": {
      "$ref": "/schemas/3.0.0/core/ext.json"
    }
  },
  "required": [
    "idempotency_key",
    "account",
    "creatives"
  ],
  "additionalProperties": true,
  "examples": [
    {
      "description": "Full sync with hosted video creative",
      "data": {
        "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
        "account": {
          "account_id": "acct_acmecorp"
        },
        "creatives": [
          {
            "creative_id": "hero_video_30s",
            "name": "Brand Hero Video 30s",
            "format_id": {
              "agent_url": "https://creative.adcontextprotocol.org",
              "id": "video_standard_30s"
            },
            "assets": {
              "video": {
                "asset_type": "video",
                "url": "https://cdn.example.com/hero-video.mp4",
                "width": 1920,
                "height": 1080,
                "duration_ms": 30000
              }
            },
            "tags": [
              "q1_2026",
              "video"
            ]
          }
        ],
        "assignments": [
          {
            "creative_id": "hero_video_30s",
            "package_id": "pkg_ctv_001"
          },
          {
            "creative_id": "hero_video_30s",
            "package_id": "pkg_ctv_002"
          }
        ]
      }
    },
    {
      "description": "Generative creative with approval",
      "data": {
        "idempotency_key": "5f8b1f3a-1234-4a5b-9cde-1234567890ab",
        "account": {
          "account_id": "acct_acmecorp"
        },
        "creatives": [
          {
            "creative_id": "holiday_hero",
            "name": "Holiday Campaign Hero",
            "format_id": {
              "agent_url": "https://creative.example.com",
              "id": "premium_bespoke_display"
            },
            "assets": {
              "product_catalog": {
                "asset_type": "catalog",
                "type": "product",
                "catalog_id": "winter-products"
              },
              "generation_prompt": {
                "asset_type": "text",
                "content": "Create a warm, festive holiday campaign featuring winter products"
              }
            },
            "tags": [
              "holiday",
              "q4_2026"
            ]
          }
        ]
      }
    },
    {
      "description": "Scoped update using creative_ids filter",
      "data": {
        "idempotency_key": "6a9c2f4b-5678-49ab-8def-fedcba987654",
        "account": {
          "account_id": "acct_acmecorp"
        },
        "creative_ids": [
          "hero_video_30s",
          "banner_300x250"
        ],
        "creatives": [
          {
            "creative_id": "hero_video_30s",
            "name": "Brand Hero Video 30s - Updated",
            "format_id": {
              "agent_url": "https://creative.adcontextprotocol.org",
              "id": "video_standard_30s"
            },
            "assets": {
              "video": {
                "asset_type": "video",
                "url": "https://cdn.example.com/updated-hero.mp4",
                "width": 1920,
                "height": 1080,
                "duration_ms": 30000
              }
            }
          },
          {
            "creative_id": "banner_300x250",
            "name": "Display Banner 300x250 - Updated",
            "format_id": {
              "agent_url": "https://creative.adcontextprotocol.org",
              "id": "display_300x250"
            },
            "assets": {
              "image": {
                "asset_type": "image",
                "url": "https://cdn.example.com/updated-banner.png",
                "width": 300,
                "height": 250
              }
            }
          }
        ]
      }
    }
  ]
}
