{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "/schemas/3.1.19/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",
  "type": "object",
  "allOf": [
    {
      "$ref": "/schemas/3.1.19/core/version-envelope.json"
    }
  ],
  "x-mutates-state": true,
  "properties": {
    "account": {
      "$ref": "/schemas/3.1.19/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.1.19/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, rehearse this sync_creatives operation without applying it. Validates the actual trafficking request in the seller's current context, including library upsert semantics, creative IDs, assignments, account-scoped gates, and seller policies, then returns what would be created/updated/deleted. This is distinct from validate_input, which only validates manifest structure against canonical/product format targets."
    },
    "validation_mode": {
      "$ref": "/schemas/3.1.19/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.1.19/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.1.19/core/context.json"
    },
    "ext": {
      "$ref": "/schemas/3.1.19/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
              }
            }
          }
        ]
      }
    }
  ]
}
