{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/creative/sync-creatives-request.json",
  "title": "Sync Creatives Request",
  "description": "Request parameters for syncing creative assets with upsert semantics. Provide at least one of creatives, assignments, or assignment_operations. assignments and assignment_operations are mutually exclusive; delete_missing: true requires creatives; assignment_operations requires validation_mode: strict.",
  "x-tool-summary": "List or synchronize creative assets, scoped updates, and media-buy assignments.",
  "type": "object",
  "allOf": [
    {
      "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/version-envelope.json"
    },
    {
      "if": {
        "properties": {
          "delete_missing": {
            "const": true
          }
        },
        "required": [
          "delete_missing"
        ]
      },
      "then": {
        "required": [
          "creatives"
        ]
      }
    },
    {
      "not": {
        "required": [
          "assignments",
          "assignment_operations"
        ]
      }
    },
    {
      "if": {
        "required": [
          "assignment_operations"
        ]
      },
      "then": {
        "properties": {
          "validation_mode": {
            "type": "string",
            "const": "strict"
          }
        }
      }
    }
  ],
  "x-mutates-state": true,
  "properties": {
    "account": {
      "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/account-ref.json",
      "description": "Account that owns these creatives."
    },
    "creatives": {
      "type": "array",
      "description": "Array of creative assets to sync (create or update)",
      "items": {
        "allOf": [
          {
            "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/creative-asset.json"
          },
          {
            "type": "object",
            "properties": {
              "revision_id": {
                "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/creative-revision-id.json",
                "description": "Optional buyer-assigned identity for this exact input-content state. Buyers may send it to any 3.2 peer; creative.supports_revisions gates reliance on immutability, echo, readback, and delivery correlation, not whether the open request shape may carry the field. Within a supporting seller, a revision_id is immutable under one creative_id: reusing it with different canonical revision content MUST fail with CREATIVE_REVISION_CONTENT_MISMATCH. Metadata and assignment fields excluded from revision content may change without minting a new revision."
              },
              "localization": {
                "description": "Sync-only materialized-localization mutation. The top-level assets are the source variant; optional locale_fallbacks declare buyer-approved language-family substitutions, and default_locale_variant_id selects the final serving fallback. An object transactionally replaces the source assets and complete locale set, omission preserves existing localization only when the top-level source assets are unchanged, and null removes localization. This field never requests translation or generation. Receivers MUST advertise get_adcp_capabilities creative.localization before accepting it.",
                "anyOf": [
                  {
                    "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/creative-localization.json"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "additionalProperties": true,
            "x-adcp-validation": {
              "verifier_constraints": {
                "revision_identity": {
                  "reliance_gate": "creative.supports_revisions",
                  "without_capability": "receiver_may_ignore_revision_id_and_buyer_must_not_rely_on_revision_guarantees",
                  "scope": [
                    "creative_id",
                    "revision_id"
                  ],
                  "check_order": [
                    "idempotency_key",
                    "revision_content"
                  ],
                  "canonical_content": {
                    "included": "all effective buyer-authored creative fields, including unknown future content fields",
                    "mutation_projection": "apply_existing_sync_field_semantics_to_prior_buyer_state_before_comparison",
                    "localization_omitted": "preserve_prior_localization_before_comparison_when_existing_localized_source_upsert_allows_omission",
                    "localization_null": "remove_localization_property_from_effective_state_before_comparison",
                    "canonicalization": "RFC_8785_JCS_of_effective_buyer_state_after_removing_exact_top_level_excluded_fields",
                    "defaults": "must_not_be_materialized_before_comparison",
                    "duplicate_json_members": "reject_request_before_comparison",
                    "excluded": [
                      "creative_id",
                      "revision_id",
                      "name",
                      "tags",
                      "status",
                      "weight",
                      "placement_refs",
                      "placement_ids"
                    ],
                    "exclusion_scope": "top_level_creative_item_only",
                    "evaluated_before": "seller_transcoding_or_normalization"
                  },
                  "representation_set_projection": {
                    "when": "creative item carries representation_selection",
                    "identity_match": "item creative_id and revision_id MUST equal representation_selection creative_id and revision_id",
                    "source_revision_binding": "use representation_selection.revision_content_digest as the complete representation-set fingerprint; MUST NOT fingerprint only the selected manifest as the source revision",
                    "selected_output_verification": "recompute representation_selection.selected_output_digest with the shared manifest projection: remove exactly top-level $schema, representation_selection, creative_id, revision_id, name, tags, status, weight, placement_refs, placement_ids, and inputs; include every other field, including unknown delivery fields",
                    "execution_review_binding": "track selected_representation_id plus selected_output_digest separately from the source revision fingerprint",
                    "execution_change": "a different selected_representation_id or selected_output_digest is an updated execution and follows ordinary re-review without minting a new buyer revision_id",
                    "explicit_reselection": "only a buyer-submitted sync_creatives item carrying a newly resolved selected output may replace accepted representation_selection lineage and trigger re-review; build_creative resolution alone does not mutate the creative library",
                    "capability_drift": "later product, placement, VAST, macro, or seller-capability changes affect future resolution and assignment validation but MUST NOT implicitly re-resolve, replace lineage, or start buyer re-review for an accepted execution",
                    "seller_inability": "when a pinned execution can no longer serve, preserve its selection lineage and use ordinary seller/system creative-status and media-buy impairment surfaces; MUST NOT silently substitute another representation",
                    "resolver_obligation": "the actor that emitted representation_selection MUST have verified the digest against the complete CreativeRepresentationSet",
                    "downstream_obligation": "retain and compare the complete-set digest for revision reuse; receiving only a selected manifest does not independently prove hidden source-set bytes"
                  },
                  "same_revision_same_content": "unchanged_unless_metadata_changed",
                  "same_revision_different_content": "CREATIVE_REVISION_CONTENT_MISMATCH",
                  "first_revision_on_unversioned_creative": {
                    "same_effective_content": "accept_as_updated_bind_revision_and_preserve_review_state",
                    "different_effective_content": "bind_only_on_accepted_update_and_require_review"
                  },
                  "different_revision_same_current_content": "accept_as_updated_make_current_preserve_review_state_and_rebind_inflight_review",
                  "previously_bound_revision_matching_historical_content": "accept_as_updated; require_review_if_content_differs_from_current",
                  "different_revision_different_content": "accept_as_updated_make_current_and_require_review",
                  "revision_omitted_with_current_revision": {
                    "same_effective_content": "preserve_current_revision_identity",
                    "different_effective_content": "accept_under_legacy_update_rules_and_clear_current_revision_identity",
                    "different_effective_content_review": "prior_approval_must_not_transfer_and_update_enters_ordinary_review",
                    "must_not_mint_seller_revision": true,
                    "historical_fingerprint_bindings": "retain"
                  },
                  "content_change_review": "prior_approval_must_not_transfer",
                  "write_order": "last_accepted_sync_wins_callers_must_serialize_revision_writes",
                  "stale_review_result": {
                    "different_fingerprint_or_not_rebound": "must_not_mutate_current_revision_or_current_status",
                    "identical_content_rebound": "apply_to_current_revision_and_attribute_result_and_webhook_to_current_revision_id"
                  },
                  "dry_run": "evaluate_against_existing_bindings_and_echo_simulated_result_but_do_not_create_or_update_bindings_tombstones_current_revision_or_review_state",
                  "fingerprint_retention": "retain_for_creative_lifetime_and_soft_purge_tombstone_lifetime; hard_purge_removes_binding"
                }
              },
              "spec": "docs/creative/task-reference/sync_creatives.mdx#creative-revisions"
            }
          },
          {
            "$comment": "Representation-set selection and sync-time localization use different revision projections and cannot be mixed in this version.",
            "if": {
              "required": [
                "representation_selection"
              ]
            },
            "then": {
              "not": {
                "required": [
                  "localization"
                ]
              },
              "x-adcp-validation": {
                "verifier_constraints": {
                  "prior_stored_localization": "must_be_absent",
                  "on_existing_localization": "reject_before_mutation_and_require_a_separate_prior_sync_with_localization_null_and_without_representation_selection"
                },
                "spec": "docs/creative/representation-sets.mdx#sync-review-and-readback"
              }
            }
          }
        ],
        "x-adcp-validation": {
          "verifier_constraints": {
            "localization_capability_gate": {
              "required_capability": "creative.localization",
              "target_count_ceiling": "creative.localization.max_target_variants_or_50",
              "locale_format_account_support": "validate_request_before_mutation",
              "on_violation": "reject_before_mutation"
            },
            "existing_localized_source_upsert": {
              "localization_omitted": "top_level_assets_must_equal_prior_source_assets",
              "source_assets_changed": "require_non_null_localization_or_null_removal",
              "on_violation": "reject_before_mutation"
            },
            "localization_replacement": {
              "scope": "top_level_assets_and_complete_localization",
              "on_failure": "prior_state_unchanged",
              "orphan_locale_variants": "must_not_be_visible"
            }
          },
          "spec": "docs/creative/task-reference/sync_creatives.mdx#native-localization"
        }
      },
      "minItems": 1,
      "maxItems": 100,
      "x-adcp-validation": {
        "unique_item_properties": [
          "creative_id"
        ],
        "spec": "docs/creative/task-reference/sync_creatives.mdx#request-parameters"
      }
    },
    "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",
      "deprecated": true,
      "description": "Deprecated additive assignment shorthand. Each entry upserts one creative-to-package assignment. Use assignment_operations for explicit assign, unassign, and replace semantics. Standalone creative agents that do not manage media buys ignore this field. A pending_review or rejected library creative MAY be assigned if the reference and other assignment constraints are valid; sellers MUST NOT reject or remove an assignment solely for its review status. Only package-approved eligible creatives may serve. See the package start_requires_all_creatives_approved policy and docs/media-buy/specification.mdx#starting-with-assigned-creatives-under-review.",
      "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"
          },
          "trackers": {
            "type": "array",
            "items": {
              "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/assignment-tracker.json"
            },
            "minItems": 1,
            "description": "Additional measurement trackers for this creative on this package only, fired alongside the creative's own trackers without changing the library creative, its revision, or its approval. Requires creative.supports_assignment_trackers: true; buyers MUST NOT send this field otherwise and unsupported agents MUST reject it with UNSUPPORTED_FEATURE. The seller MUST fire every accepted tracker at its declared event or reject the assignment through existing assignment errors; trackers MUST NOT be silently dropped. Creative and assignment trackers together count against the effective format's tracker-slot limits, including canonical params.slots[].max and legacy repeatable-group max_count. Each assignment tracker consumes one compatible slot occurrence without moving creative assets; reject if no allocation satisfies each slot's type, event role, and count constraints. Each accepted occurrence fires once per logical event; identical URLs are not deduplicated. A supplied list replaces the prior assignment tracker list. Omission on an additive upsert preserves existing assignment trackers. To clear them, atomically unassign then assign without this field, retaining any other authored assignment settings. Empty arrays and null are not accepted.",
            "x-added-in": "3.3.0"
          },
          "landing_page_url": {
            "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/macro-bearing-url.json",
            "description": "Override the creative's click-through destination for this creative on this package only, without changing the library creative. The override applies to every click-through destination for this assignment, including per-state destinations; partial application MUST be rejected. AdCP macros follow the same rules as the creative's own click-through without declarations, retaining existing 3.x compatibility behavior. Declarations on the original creative assets do not transfer to this URL. Requires creative.supports_assignment_landing_page: true; buyers MUST NOT send this field otherwise and sellers without the capability MUST reject it with UNSUPPORTED_FEATURE. The seller MUST serve the override or reject the assignment through existing assignment errors, including when an embedded HTML, JavaScript, or VAST click cannot be overridden. Creative approval remains valid; destination review applies to the assignment. Omission on an additive upsert preserves an existing override. To restore inheritance, atomically unassign then assign without this field; null is not accepted.",
            "x-added-in": "3.3.0"
          },
          "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,
        "x-adcp-validation": {
          "verifier_constraints": {
            "product_format_locale_policy": {
              "scope": "every_effective_product_and_placement_format_option_where_assignment_may_serve",
              "range_matching": "rfc4647_basic_filtering",
              "eligible_variant_set": "filter_before_buyer_lookup_fallback_or_default",
              "minimum_eligible_variants_per_scope": 1,
              "serve_default": "default_locale_variant_id_must_be_eligible",
              "policy_lifecycle": "snapshot_effective_policy_at_assignment_acceptance",
              "on_violation": "CREATIVE_LOCALE_NOT_ACCEPTED"
            }
          },
          "spec": "docs/creative/task-reference/sync_creatives.mdx#native-localization"
        }
      },
      "minItems": 1
    },
    "assignment_operations": {
      "type": "array",
      "description": "Explicit, ordered assignment mutations. These operations may be sent without creatives to traffic existing creative IDs independently from MediaBuy commercial control. The entire request is atomic under idempotency_key and therefore requires strict validation; lenient partial processing is not permitted. A pending_review or rejected library creative MAY be assigned if the reference and other assignment constraints are valid; sellers MUST NOT reject or remove an assignment solely for its review status. Only package-approved eligible creatives may serve. See the package start_requires_all_creatives_approved policy and docs/media-buy/specification.mdx#starting-with-assigned-creatives-under-review.",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "type": "object",
        "discriminator": {
          "propertyName": "operation"
        },
        "oneOf": [
          {
            "title": "Assign or update",
            "properties": {
              "operation": {
                "const": "assign"
              },
              "creative_id": {
                "type": "string",
                "minLength": 1,
                "x-entity": "creative"
              },
              "package_id": {
                "type": "string",
                "minLength": 1,
                "x-entity": "package"
              },
              "trackers": {
                "type": "array",
                "items": {
                  "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/assignment-tracker.json"
                },
                "minItems": 1,
                "description": "Additional measurement trackers for this creative on this package only, fired alongside the creative's own trackers without changing the library creative, its revision, or its approval. Requires creative.supports_assignment_trackers: true; buyers MUST NOT send this field otherwise and unsupported agents MUST reject it with UNSUPPORTED_FEATURE. The seller MUST fire every accepted tracker at its declared event or reject the assignment through existing assignment errors; trackers MUST NOT be silently dropped. Creative and assignment trackers together count against the effective format's tracker-slot limits, including canonical params.slots[].max and legacy repeatable-group max_count. Each assignment tracker consumes one compatible slot occurrence without moving creative assets; reject if no allocation satisfies each slot's type, event role, and count constraints. Each accepted occurrence fires once per logical event; identical URLs are not deduplicated. A supplied list replaces the prior assignment tracker list. Omission on an additive upsert preserves existing assignment trackers. To clear them, atomically unassign then assign without this field, retaining any other authored assignment settings. Empty arrays and null are not accepted.",
                "x-added-in": "3.3.0"
              },
              "landing_page_url": {
                "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/macro-bearing-url.json",
                "description": "Override the creative's click-through destination for this creative on this package only, without changing the library creative. The override applies to every click-through destination for this assignment, including per-state destinations; partial application MUST be rejected. AdCP macros follow the same rules as the creative's own click-through without declarations, retaining existing 3.x compatibility behavior. Declarations on the original creative assets do not transfer to this URL. Requires creative.supports_assignment_landing_page: true; buyers MUST NOT send this field otherwise and sellers without the capability MUST reject it with UNSUPPORTED_FEATURE. The seller MUST serve the override or reject the assignment through existing assignment errors, including when an embedded HTML, JavaScript, or VAST click cannot be overridden. Creative approval remains valid; destination review applies to the assignment. Omission on an additive upsert preserves an existing override. To restore inheritance, atomically unassign then assign without this field; null is not accepted.",
                "x-added-in": "3.3.0"
              },
              "weight": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "placement_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                },
                "minItems": 1,
                "uniqueItems": true
              }
            },
            "required": [
              "operation",
              "creative_id",
              "package_id"
            ],
            "additionalProperties": false,
            "x-adcp-validation": {
              "verifier_constraints": {
                "product_format_locale_policy": {
                  "scope": "every_effective_product_and_placement_format_option_where_assignment_may_serve",
                  "range_matching": "rfc4647_basic_filtering",
                  "eligible_variant_set": "filter_before_buyer_lookup_fallback_or_default",
                  "minimum_eligible_variants_per_scope": 1,
                  "serve_default": "default_locale_variant_id_must_be_eligible",
                  "policy_lifecycle": "snapshot_effective_policy_at_assignment_acceptance",
                  "on_violation": "CREATIVE_LOCALE_NOT_ACCEPTED"
                }
              },
              "spec": "docs/creative/task-reference/sync_creatives.mdx#native-localization"
            }
          },
          {
            "title": "Unassign",
            "properties": {
              "operation": {
                "const": "unassign"
              },
              "creative_id": {
                "type": "string",
                "minLength": 1,
                "x-entity": "creative"
              },
              "package_id": {
                "type": "string",
                "minLength": 1,
                "x-entity": "package"
              }
            },
            "required": [
              "operation",
              "creative_id",
              "package_id"
            ],
            "additionalProperties": false
          },
          {
            "title": "Replace assignment",
            "properties": {
              "operation": {
                "const": "replace"
              },
              "creative_id": {
                "type": "string",
                "minLength": 1,
                "description": "Replacement creative ID.",
                "x-entity": "creative"
              },
              "replaces_creative_id": {
                "type": "string",
                "minLength": 1,
                "description": "Currently assigned creative ID to remove atomically.",
                "x-entity": "creative"
              },
              "package_id": {
                "type": "string",
                "minLength": 1,
                "x-entity": "package"
              },
              "weight": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "placement_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                },
                "minItems": 1,
                "uniqueItems": true
              }
            },
            "required": [
              "operation",
              "creative_id",
              "replaces_creative_id",
              "package_id"
            ],
            "additionalProperties": false,
            "x-adcp-validation": {
              "verifier_constraints": {
                "product_format_locale_policy": {
                  "scope": "every_effective_product_and_placement_format_option_where_assignment_may_serve",
                  "range_matching": "rfc4647_basic_filtering",
                  "eligible_variant_set": "filter_before_buyer_lookup_fallback_or_default",
                  "minimum_eligible_variants_per_scope": 1,
                  "serve_default": "default_locale_variant_id_must_be_eligible",
                  "policy_lifecycle": "snapshot_effective_policy_at_assignment_acceptance",
                  "on_violation": "CREATIVE_LOCALE_NOT_ACCEPTED"
                }
              },
              "spec": "docs/creative/task-reference/sync_creatives.mdx#native-localization"
            }
          },
          {
            "title": "Merge seller copy",
            "description": "Declares that merged_creative_id, a seller-assigned creative currently assigned to package_id, is the same creative as creative_id. On success the seller moves that assignment's serving object, approval, weight, and placement routing to (creative_id, package_id) without re-trafficking it, and merged_creative_id no longer has an assignment on the package. Unlike replace, which traffics creative_id as a new object, merge preserves delivery continuity. Requires creative.supports_assignment_merge.",
            "properties": {
              "operation": {
                "const": "merge"
              },
              "creative_id": {
                "type": "string",
                "minLength": 1,
                "description": "Buyer's creative that takes over the assignment. It need not already be assigned to package_id.",
                "x-entity": "creative"
              },
              "package_id": {
                "type": "string",
                "minLength": 1,
                "x-entity": "package"
              },
              "merged_creative_id": {
                "type": "string",
                "minLength": 1,
                "description": "Seller-created creative (one that entered the library outside sync_creatives, under a seller-assigned creative_id) currently assigned to package_id that the seller verifies is the same creative as creative_id.",
                "x-entity": "creative"
              }
            },
            "required": [
              "operation",
              "creative_id",
              "package_id",
              "merged_creative_id"
            ],
            "additionalProperties": false,
            "x-added-in": "3.3.0",
            "x-adcp-validation": {
              "verifier_constraints": {
                "capability_gate": {
                  "required_capability": "creative.supports_assignment_merge",
                  "without_capability": "UNSUPPORTED_FEATURE"
                },
                "on_rejection": {
                  "evaluation": "evaluate_every_merge_in_request; any_rejection_fails_whole_request_and_changes_no_assignment",
                  "error_code": "CREATIVE_MERGE_REJECTED",
                  "details": "error-details/creative-merge-rejected.json rejections[] one entry per rejected merge",
                  "reasons": {
                    "not_on_package": "merged_creative_id_unknown_or_not_seller_assigned_or_not_assigned_to_package_in_account; reported_uniformly",
                    "not_supported": "seller_cannot_merge_this_pairing_on_this_package",
                    "format_mismatch": "creative_id_cannot_take_over_merged_creative_serving_object",
                    "content_mismatch": "seller_judges_not_same_creative"
                  }
                },
                "on_pending_confirmation": "submitted_task; completion_artifact_carries_merges_or_CREATIVE_MERGE_REJECTED",
                "on_success": {
                  "readback": "response_merges_one_entry_per_applied_merge",
                  "approval": "inherit_merged_creative_approval_on_package_and_must_not_re_review_unless_content_differs",
                  "merged_creative": "remove_assignment_on_package_only; not_purged",
                  "delivery_attribution": "report_under_creative_id_from_merge_time; prior_delivery_stays_under_merged_creative_id_and_must_not_be_restated"
                }
              },
              "spec": "docs/creative/task-reference/sync_creatives.mdx#merging-a-seller-created-copy"
            }
          }
        ]
      }
    },
    "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. A seller that declares creative.stable_creative_ids never archives creatives that entered its library outside sync_creatives; other sellers may archive them, so buyers SHOULD NOT use delete_missing against such sellers when seller-created creatives matter. 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": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/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": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/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": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/context.json"
    },
    "ext": {
      "$ref": "https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/ext.json"
    }
  },
  "required": [
    "idempotency_key",
    "account"
  ],
  "anyOf": [
    {
      "required": [
        "creatives"
      ]
    },
    {
      "required": [
        "assignments"
      ]
    },
    {
      "required": [
        "assignment_operations"
      ]
    }
  ],
  "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_kind": "video_hosted",
            "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_kind": "image",
            "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_kind": "video_hosted",
            "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_kind": "image",
            "assets": {
              "image": {
                "asset_type": "image",
                "url": "https://cdn.example.com/updated-banner.png",
                "width": 300,
                "height": 250
              }
            }
          }
        ]
      }
    }
  ]
}
