{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "/schemas/3.1.0-rc.4/core/format.json",
  "title": "Format",
  "description": "Represents a creative format with its requirements",
  "type": "object",
  "$defs": {
    "baseIndividualAsset": {
      "type": "object",
      "properties": {
        "item_type": {
          "type": "string",
          "const": "individual",
          "description": "Discriminator indicating this is an individual asset"
        },
        "asset_id": {
          "type": "string",
          "description": "Unique identifier for this asset. Creative manifests MUST use this exact value as the key in the assets object."
        },
        "asset_role": {
          "type": "string",
          "description": "Descriptive label for this asset's purpose (e.g., 'hero_image', 'logo', 'third_party_tracking'). For documentation and UI display only — manifests key assets by asset_id, not asset_role."
        },
        "required": {
          "type": "boolean",
          "description": "Whether this asset is required (true) or optional (false). Required assets must be provided for a valid creative. Optional assets enhance the creative but are not mandatory."
        },
        "overlays": {
          "type": "array",
          "description": "Publisher-controlled elements rendered on top of buyer content at this asset's position (e.g., video player controls, publisher logos). Creative agents should avoid placing critical content (CTAs, logos, key copy) within overlay bounds.",
          "items": { "$ref": "/schemas/3.1.0-rc.4/core/overlay.json" }
        },
        "asset_group_id": {
          "type": "string",
          "description": "Optional canonical asset_group_id this slot fills, drawn from /schemas/core/asset-group-vocabulary.json. Lets buyers and migration tools resolve v1 author-invented slot names (e.g., `click_url`) to canonical names (e.g., `landing_page_url`). Validators MAY soft-warn when a v1 slot's asset_id is a known alias but no asset_group_id is declared."
        }
      },
      "required": ["item_type", "asset_id", "asset_type", "required"]
    },
    "baseGroupAsset": {
      "type": "object",
      "properties": {
        "asset_id": {
          "type": "string",
          "description": "Identifier for this asset within the group"
        },
        "asset_role": {
          "type": "string",
          "description": "Descriptive label for this asset's purpose. For documentation and UI display only — manifests key assets by asset_id, not asset_role."
        },
        "asset_group_id": {
          "type": "string",
          "description": "Optional canonical asset_group_id this slot fills, drawn from /schemas/core/asset-group-vocabulary.json. Same semantics as on baseIndividualAsset — lets buyers and migration tools resolve v1 author-invented slot names to canonical names."
        },
        "required": {
          "type": "boolean",
          "description": "Whether this asset is required within each repetition of the group",
          "default": false
        },
        "overlays": {
          "type": "array",
          "description": "Publisher-controlled elements rendered on top of buyer content at this asset's position (e.g., carousel navigation arrows, slide indicators). Creative agents should avoid placing critical content within overlay bounds.",
          "items": { "$ref": "/schemas/3.1.0-rc.4/core/overlay.json" }
        }
      },
      "required": ["asset_id", "asset_type", "required"]
    }
  },
  "properties": {
    "format_id": {
      "$ref": "/schemas/3.1.0-rc.4/core/format-id.json",
      "description": "This format's own identifier — a structured object {agent_url, id}, not a string. See /schemas/core/format-id.json for the full shape."
    },
    "name": {
      "type": "string",
      "description": "Human-readable format name"
    },
    "description": {
      "type": "string",
      "description": "Plain text explanation of what this format does and what assets it requires"
    },
    "example_url": {
      "type": "string",
      "format": "uri",
      "description": "Optional URL to showcase page with examples and interactive demos of this format"
    },
    "accepts_parameters": {
      "type": "array",
      "description": "List of parameters this format accepts in format_id. Template formats define which parameters (dimensions, duration, etc.) can be specified when instantiating the format. Empty or omitted means this is a concrete format with fixed parameters.",
      "items": {
        "$ref": "/schemas/3.1.0-rc.4/enums/format-id-parameter.json"
      },
      "uniqueItems": true
    },
    "renders": {
      "type": "array",
      "description": "Specification of rendered pieces for this format. Most formats produce a single render. Companion ad formats (video + banner), adaptive formats, and multi-placement formats produce multiple renders. Each render specifies its role and dimensions.",
      "items": {
        "type": "object",
        "properties": {
          "role": {
            "type": "string",
            "description": "Semantic role of this rendered piece (e.g., 'primary', 'companion', 'mobile_variant')"
          },
          "parameters_from_format_id": {
            "type": "boolean",
            "description": "When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly."
          },
          "dimensions": {
            "type": "object",
            "description": "Dimensions for this rendered piece. Defaults to pixels when unit is absent.",
            "properties": {
              "width": {
                "type": "number",
                "exclusiveMinimum": 0,
                "description": "Fixed width. Interpretation depends on unit (default: pixels)."
              },
              "height": {
                "type": "number",
                "exclusiveMinimum": 0,
                "description": "Fixed height. Interpretation depends on unit (default: pixels)."
              },
              "min_width": {
                "type": "number",
                "exclusiveMinimum": 0,
                "description": "Minimum width for responsive renders"
              },
              "min_height": {
                "type": "number",
                "exclusiveMinimum": 0,
                "description": "Minimum height for responsive renders"
              },
              "max_width": {
                "type": "number",
                "exclusiveMinimum": 0,
                "description": "Maximum width for responsive renders"
              },
              "max_height": {
                "type": "number",
                "exclusiveMinimum": 0,
                "description": "Maximum height for responsive renders"
              },
              "unit": {
                "$ref": "/schemas/3.1.0-rc.4/enums/dimension-unit.json",
                "description": "Unit of measurement for width/height values. Defaults to 'px' when absent. Print formats use 'inches' or 'cm'."
              },
              "responsive": {
                "type": "object",
                "description": "Indicates which dimensions are responsive/fluid",
                "properties": {
                  "width": {
                    "type": "boolean"
                  },
                  "height": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "width",
                  "height"
                ]
              },
              "aspect_ratio": {
                "type": "string",
                "description": "Fixed aspect ratio constraint (e.g., '16:9', '4:3', '1:1', '1.91:1')",
                "pattern": "^\\d+(\\.\\d+)?:\\d+(\\.\\d+)?$"
              }
            }
          }
        },
        "required": [
          "role"
        ],
        "oneOf": [
          {
            "required": [
              "dimensions"
            ],
            "not": {
              "required": [
                "parameters_from_format_id"
              ]
            }
          },
          {
            "required": [
              "parameters_from_format_id"
            ],
            "properties": {
              "parameters_from_format_id": {
                "const": true
              }
            },
            "not": {
              "required": [
                "dimensions"
              ]
            }
          }
        ]
      },
      "minItems": 1
    },
    "assets": {
      "type": "array",
      "description": "Array of all assets supported for this format. Each asset is identified by its asset_id, which must be used as the key in creative manifests. Use the 'required' boolean on each asset to indicate whether it's mandatory.",
      "items": {
        "oneOf": [
          {
            "title": "IndividualImageAsset",
            "description": "Image asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "image" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/image-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualVideoAsset",
            "description": "Video asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "video" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/video-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualAudioAsset",
            "description": "Audio asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "audio" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/audio-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualTextAsset",
            "description": "Text asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "text" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/text-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualMarkdownAsset",
            "description": "Markdown asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "markdown" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/markdown-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualHtmlAsset",
            "description": "HTML asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "html" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/html-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualCssAsset",
            "description": "CSS asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "css" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/css-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualJavaScriptAsset",
            "description": "JavaScript asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "javascript" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/javascript-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualZipAsset",
            "description": "Zip-bundled asset (HTML5 banner bundles, etc.)",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "zip" }
            }
          },
          {
            "title": "IndividualVastAsset",
            "description": "VAST asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "vast" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/vast-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualDaastAsset",
            "description": "DAAST asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "daast" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/daast-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualUrlAsset",
            "description": "URL asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "url" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/url-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualWebhookAsset",
            "description": "Webhook asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "webhook" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/webhook-asset-requirements.json" }
            }
          },
          {
            "title": "IndividualBriefAsset",
            "description": "Brief asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "brief" }
            }
          },
          {
            "title": "IndividualCatalogAsset",
            "description": "Catalog asset",
            "allOf": [{ "$ref": "#/$defs/baseIndividualAsset" }],
            "properties": {
              "item_type": { "const": "individual" },
              "asset_type": { "const": "catalog" },
              "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/catalog-requirements.json" }
            }
          },
          {
            "title": "RepeatableGroupAsset",
            "description": "Repeatable asset group (for carousels, slideshows, playlists, etc.)",
            "type": "object",
            "properties": {
              "item_type": {
                "type": "string",
                "const": "repeatable_group",
                "description": "Discriminator indicating this is a repeatable asset group"
              },
              "asset_group_id": {
                "type": "string",
                "description": "Identifier for this asset group (e.g., 'product', 'slide', 'card')"
              },
              "required": {
                "type": "boolean",
                "description": "Whether this asset group is required. If true, at least min_count repetitions must be provided."
              },
              "min_count": {
                "type": "integer",
                "description": "Minimum number of repetitions required (if group is required) or allowed (if optional)",
                "minimum": 0
              },
              "max_count": {
                "type": "integer",
                "description": "Maximum number of repetitions allowed",
                "minimum": 1
              },
              "selection_mode": {
                "type": "string",
                "description": "How the platform uses repetitions of this group. 'sequential' means all items display in order (carousels, playlists). 'optimize' means the platform selects the best-performing combination from alternatives (asset group optimization like Meta Advantage+ or Google Pmax).",
                "enum": [
                  "sequential",
                  "optimize"
                ],
                "default": "sequential"
              },
              "assets": {
                "type": "array",
                "description": "Assets within each repetition of this group",
                "items": {
                  "discriminator": {
                    "propertyName": "asset_type"
                  },
                  "oneOf": [
                    {
                      "title": "GroupImageAsset",
                      "description": "Image asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "image" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/image-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupVideoAsset",
                      "description": "Video asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "video" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/video-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupAudioAsset",
                      "description": "Audio asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "audio" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/audio-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupTextAsset",
                      "description": "Text asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "text" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/text-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupMarkdownAsset",
                      "description": "Markdown asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "markdown" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/markdown-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupHtmlAsset",
                      "description": "HTML asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "html" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/html-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupCssAsset",
                      "description": "CSS asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "css" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/css-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupJavaScriptAsset",
                      "description": "JavaScript asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "javascript" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/javascript-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupZipAsset",
                      "description": "Zip-bundled asset in group (HTML5 banner bundles, etc.)",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "zip" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupVastAsset",
                      "description": "VAST asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "vast" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/vast-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupDaastAsset",
                      "description": "DAAST asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "daast" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/daast-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupUrlAsset",
                      "description": "URL asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "url" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/url-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    },
                    {
                      "title": "GroupWebhookAsset",
                      "description": "Webhook asset in group",
                      "allOf": [{ "$ref": "#/$defs/baseGroupAsset" }],
                      "properties": {
                        "asset_type": { "const": "webhook" },
                        "requirements": { "$ref": "/schemas/3.1.0-rc.4/core/requirements/webhook-asset-requirements.json" }
                      },
                      "required": ["asset_type"]
                    }
                  ]
                }
              }
            },
            "required": ["item_type", "asset_group_id", "required", "min_count", "max_count", "assets"]
          }
        ]
      }
    },
    "delivery": {
      "type": "object",
      "description": "Delivery method specifications (e.g., hosted, VAST, third-party tags)",
      "additionalProperties": true
    },
    "supported_macros": {
      "type": "array",
      "description": "List of universal macros supported by this format (e.g., MEDIA_BUY_ID, CACHEBUSTER, DEVICE_ID). Used for validation and developer tooling. See docs/creative/universal-macros.mdx for full documentation.",
      "items": {
        "anyOf": [
          { "$ref": "/schemas/3.1.0-rc.4/enums/universal-macro.json" },
          { "type": "string", "description": "Custom or publisher-specific macro name" }
        ]
      }
    },
    "input_format_ids": {
      "type": "array",
      "description": "Array of format IDs this format accepts as input creative manifests. When present, indicates this format can take existing creatives in these formats as input. Omit for formats that work from raw assets (images, text, etc.) rather than existing creatives.",
      "items": {
        "$ref": "/schemas/3.1.0-rc.4/core/format-id.json"
      }
    },
    "output_format_ids": {
      "type": "array",
      "description": "Array of format IDs that this format can produce as output. When present, indicates this format can build creatives in these output formats (e.g., a multi-publisher template format might produce standard display formats across many publishers). Omit for formats that produce a single fixed output (the format itself).",
      "items": {
        "$ref": "/schemas/3.1.0-rc.4/core/format-id.json"
      }
    },
    "format_card": {
      "type": "object",
      "description": "Optional standard visual card (300x400px) for displaying this format in user interfaces. Can be rendered via preview_creative or pre-generated.",
      "properties": {
        "format_id": {
          "$ref": "/schemas/3.1.0-rc.4/core/format-id.json",
          "description": "Creative format defining the card layout (typically format_card_standard)"
        },
        "manifest": {
          "type": "object",
          "description": "Asset manifest for rendering the card, structure defined by the format",
          "additionalProperties": true
        }
      },
      "required": [
        "format_id",
        "manifest"
      ],
      "additionalProperties": true
    },
    "accessibility": {
      "type": "object",
      "description": "Accessibility posture of this format. Declares the WCAG conformance level that creatives produced by this format will meet.",
      "properties": {
        "wcag_level": {
          "$ref": "/schemas/3.1.0-rc.4/enums/wcag-level.json",
          "description": "WCAG conformance level that this format achieves. For format-rendered creatives, the format guarantees this level. For opaque creatives, the format requires assets that self-certify to this level."
        },
        "requires_accessible_assets": {
          "type": "boolean",
          "description": "When true, all assets with x-accessibility fields must include those fields. For inspectable assets (image, video, audio), this means providing accessibility metadata like alt_text or captions. For opaque assets (HTML, JavaScript), this means providing self-declared accessibility properties."
        }
      },
      "required": ["wcag_level"]
    },
    "supported_disclosure_positions": {
      "type": "array",
      "description": "Disclosure positions this format can render. Buyers use this to determine whether a format can satisfy their compliance requirements before submitting a creative. When omitted, the format makes no disclosure rendering guarantees — creative agents SHOULD treat this as incompatible with briefs that require specific disclosure positions. Values correspond to positions on creative-brief.json required_disclosures.",
      "items": {
        "$ref": "/schemas/3.1.0-rc.4/enums/disclosure-position.json"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "disclosure_capabilities": {
      "type": "array",
      "description": "Structured disclosure capabilities per position with persistence modes. Declares which persistence behaviors each disclosure position supports, enabling persistence-aware matching against provenance render guidance and brief requirements. When present, supersedes supported_disclosure_positions for persistence-aware queries. The flat supported_disclosure_positions field is retained for backward compatibility. Each position MUST appear at most once; validators and agents SHOULD reject duplicates.",
      "items": {
        "type": "object",
        "properties": {
          "position": {
            "$ref": "/schemas/3.1.0-rc.4/enums/disclosure-position.json",
            "description": "The disclosure position"
          },
          "persistence": {
            "type": "array",
            "description": "Persistence modes this position supports",
            "items": {
              "$ref": "/schemas/3.1.0-rc.4/enums/disclosure-persistence.json"
            },
            "minItems": 1,
            "uniqueItems": true
          }
        },
        "required": ["position", "persistence"],
        "additionalProperties": true
      },
      "minItems": 1
    },
    "format_card_detailed": {
      "type": "object",
      "description": "Optional detailed card with carousel and full specifications. Provides rich format documentation similar to ad spec pages.",
      "properties": {
        "format_id": {
          "$ref": "/schemas/3.1.0-rc.4/core/format-id.json",
          "description": "Creative format defining the detailed card layout (typically format_card_detailed)"
        },
        "manifest": {
          "type": "object",
          "description": "Asset manifest for rendering the detailed card, structure defined by the format",
          "additionalProperties": true
        }
      },
      "required": [
        "format_id",
        "manifest"
      ],
      "additionalProperties": true
    },
    "reported_metrics": {
      "type": "array",
      "description": "Metrics this format can produce in delivery reporting. Buyers receive the intersection of format reported_metrics and product available_metrics. If omitted, the format defers entirely to product-level metric declarations.",
      "items": {
        "$ref": "/schemas/3.1.0-rc.4/enums/available-metric.json"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "pricing_options": {
      "type": "array",
      "description": "Pricing options for this format. Used by transformation and generation agents that charge per format adapted, per image generated, or per unit of work. Present when the request included include_pricing=true and account. Ad servers and library-based agents expose pricing on list_creatives instead.",
      "items": {
        "$ref": "/schemas/3.1.0-rc.4/core/vendor-pricing-option.json"
      },
      "minItems": 1
    },
    "canonical": {
      "$ref": "/schemas/3.1.0-rc.4/core/canonical-projection-ref.json",
      "description": "Optional v2 canonical-projection annotation. Always an object — bare-string shorthand (`canonical: \"image\"`) is not supported; the minimal form is `canonical: { \"kind\": \"image\" }`. Carries `kind` (which canonical the v1 format projects to) plus optional `asset_source` and `slots_override` for cases where the v1 format's shape doesn't follow the canonical's defaults (e.g., generative entries whose input is `generation_prompt: text` instead of `image_main: image`).\n\nWhen set, SDKs use this annotation as the authoritative v1 → v2 mapping for this format, bypassing the [v1 canonical mapping registry](/schemas/registries/v1-canonical-mapping.json) lookup. Combined with the slot-level `asset_group_id` declarations on each `assets[i]` entry, a v1 format declaration with `canonical` set is fully self-describing for v1↔v2 translation.\n\nResolution order for SDK projection from v1 wire shape to v2 (per RFC #3305 amendment #3767):\n1. If this `canonical` field is set, use it (seller-declared, highest priority). Apply `asset_source` and `slots_override` from the projection ref when present; otherwise inherit the canonical's defaults.\n2. Else, look up `format_id` in the canonical mapping registry's `format_id_glob` entries.\n3. Else, attempt structural match against the registry's `structural` entries (asset types, slot shape, vast_versions, etc.).\n4. Else, fail closed: SDK MUST NOT emit `format_options` for products carrying this format. Surface `FORMAT_PROJECTION_FAILED` on the response `errors[]` suggesting the seller add an explicit `canonical` annotation or file a registry entry.\n\nWhen `canonical.kind` is `custom`, the seller MUST also declare `canonical_format_shape` and `canonical_format_schema` (parallel to ProductFormatDeclaration's `format_shape` and `format_schema`) so buyer SDKs can fetch the seller's custom format schema.\n\nSee `canonical-projection-ref.json` for full projection semantics and examples (default-slot case, generative case, brief-driven case)."
    },
    "canonical_parameters": {
      "$ref": "/schemas/3.1.0-rc.4/core/product-format-declaration.json",
      "deprecated": true,
      "description": "**DEPRECATED in 3.1. Removed at 4.0.** Use `v1_format_ref` on the v2 `ProductFormatDeclaration` instead — the seller authors a v2 declaration (in `Product.format_options` or `creative.supported_formats`) and links it back to this v1 format via `v1_format_ref: { agent_url, id }`. The directional link from v2 → v1 is the same fact as `canonical_parameters` without the parallel-shape drift surface (v1 file and `canonical_parameters` were two declarations of the same thing; hand-authored, drifting silently).\n\nMigration: every seller currently authoring `canonical_parameters` SHOULD migrate to authoring a v2 declaration on the corresponding product (or capability) with `v1_format_ref` pointing back at this v1 format. v1 files become pure v1 again — no v2-shape mirroring.\n\n*Legacy behavior, retained for 3.1–3.x backward compatibility:* When `canonical` is set, this field carries the full ProductFormatDeclaration that the SDK projects this v1 format into. The `format_kind` MUST equal the `canonical` field value (validators enforce). When set, this is the authoritative source for SDK v1→v2 projection — the registry's structural-match parameter inference is bypassed. SDKs reading 3.1 catalogs MUST continue to honor `canonical_parameters` when present; 4.0+ SDKs MAY reject the field. New code SHOULD NOT emit this field.\n\n**Drift contract (still normative while supported).** Hand-authored `canonical_parameters` MUST satisfy the *narrows* relation against this v1 format's `requirements` and `assets[*]` shape (see canonical-formats.mdx 'Narrows — formal definition'). SDKs that read this v1 file SHOULD lint-time check the equivalence at build/load and emit `FORMAT_PROJECTION_FAILED` if the two disagree."
    }
  },
  "required": [
    "format_id",
    "name"
  ],
  "allOf": [
    {
      "if": {
        "required": ["canonical_parameters"]
      },
      "then": {
        "required": ["canonical"],
        "properties": {
          "canonical_parameters": {
            "type": "object",
            "properties": {
              "format_kind": {
                "$comment": "Must agree with the sibling `canonical.kind` field — validators SHOULD assert this constraint at build time. JSON Schema can't directly express cross-field equality without ext keywords."
              }
            }
          }
        }
      }
    }
  ],
  "additionalProperties": true
}
