diff --git a/schemas/cache/bundled/content-standards/calibrate-content-request.json b/schemas/cache/bundled/content-standards/calibrate-content-request.json index beae4e6f..4bd0342d 100644 --- a/schemas/cache/bundled/content-standards/calibrate-content-request.json +++ b/schemas/cache/bundled/content-standards/calibrate-content-request.json @@ -1888,7 +1888,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.329Z", + "generatedAt": "2026-04-22T04:00:56.627Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/calibrate-content-response.json b/schemas/cache/bundled/content-standards/calibrate-content-response.json index 3f6de003..42e8e5e3 100644 --- a/schemas/cache/bundled/content-standards/calibrate-content-response.json +++ b/schemas/cache/bundled/content-standards/calibrate-content-response.json @@ -161,7 +161,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.331Z", + "generatedAt": "2026-04-22T04:00:56.629Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/create-content-standards-request.json b/schemas/cache/bundled/content-standards/create-content-standards-request.json index 01febd18..71f11c6c 100644 --- a/schemas/cache/bundled/content-standards/create-content-standards-request.json +++ b/schemas/cache/bundled/content-standards/create-content-standards-request.json @@ -4081,7 +4081,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.338Z", + "generatedAt": "2026-04-22T04:00:56.635Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/create-content-standards-response.json b/schemas/cache/bundled/content-standards/create-content-standards-response.json index a7683012..c9032fd0 100644 --- a/schemas/cache/bundled/content-standards/create-content-standards-response.json +++ b/schemas/cache/bundled/content-standards/create-content-standards-response.json @@ -109,7 +109,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.341Z", + "generatedAt": "2026-04-22T04:00:56.638Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/get-content-standards-request.json b/schemas/cache/bundled/content-standards/get-content-standards-request.json index f70575c8..968ed112 100644 --- a/schemas/cache/bundled/content-standards/get-content-standards-request.json +++ b/schemas/cache/bundled/content-standards/get-content-standards-request.json @@ -31,7 +31,7 @@ "standards_id" ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.342Z", + "generatedAt": "2026-04-22T04:00:56.638Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/get-content-standards-response.json b/schemas/cache/bundled/content-standards/get-content-standards-response.json index 37905295..23fcca6f 100644 --- a/schemas/cache/bundled/content-standards/get-content-standards-response.json +++ b/schemas/cache/bundled/content-standards/get-content-standards-response.json @@ -4310,7 +4310,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.348Z", + "generatedAt": "2026-04-22T04:00:56.644Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/get-media-buy-artifacts-request.json b/schemas/cache/bundled/content-standards/get-media-buy-artifacts-request.json index 4bb7d483..088468a1 100644 --- a/schemas/cache/bundled/content-standards/get-media-buy-artifacts-request.json +++ b/schemas/cache/bundled/content-standards/get-media-buy-artifacts-request.json @@ -227,7 +227,7 @@ "media_buy_id" ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.351Z", + "generatedAt": "2026-04-22T04:00:56.648Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/get-media-buy-artifacts-response.json b/schemas/cache/bundled/content-standards/get-media-buy-artifacts-response.json index 7a273282..2abd2403 100644 --- a/schemas/cache/bundled/content-standards/get-media-buy-artifacts-response.json +++ b/schemas/cache/bundled/content-standards/get-media-buy-artifacts-response.json @@ -2056,7 +2056,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.354Z", + "generatedAt": "2026-04-22T04:00:56.651Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/list-content-standards-request.json b/schemas/cache/bundled/content-standards/list-content-standards-request.json index f104706a..dff6ab82 100644 --- a/schemas/cache/bundled/content-standards/list-content-standards-request.json +++ b/schemas/cache/bundled/content-standards/list-content-standards-request.json @@ -114,7 +114,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.356Z", + "generatedAt": "2026-04-22T04:00:56.653Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/list-content-standards-response.json b/schemas/cache/bundled/content-standards/list-content-standards-response.json index a20facda..30bfe965 100644 --- a/schemas/cache/bundled/content-standards/list-content-standards-response.json +++ b/schemas/cache/bundled/content-standards/list-content-standards-response.json @@ -4339,7 +4339,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.362Z", + "generatedAt": "2026-04-22T04:00:56.658Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/update-content-standards-request.json b/schemas/cache/bundled/content-standards/update-content-standards-request.json index 0fe32a19..0cd222ae 100644 --- a/schemas/cache/bundled/content-standards/update-content-standards-request.json +++ b/schemas/cache/bundled/content-standards/update-content-standards-request.json @@ -4070,7 +4070,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.369Z", + "generatedAt": "2026-04-22T04:00:56.667Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/update-content-standards-response.json b/schemas/cache/bundled/content-standards/update-content-standards-response.json index 7e962091..1b4ddb78 100644 --- a/schemas/cache/bundled/content-standards/update-content-standards-response.json +++ b/schemas/cache/bundled/content-standards/update-content-standards-response.json @@ -124,7 +124,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.372Z", + "generatedAt": "2026-04-22T04:00:56.671Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/validate-content-delivery-request.json b/schemas/cache/bundled/content-standards/validate-content-delivery-request.json index d6f5e92e..7da59b23 100644 --- a/schemas/cache/bundled/content-standards/validate-content-delivery-request.json +++ b/schemas/cache/bundled/content-standards/validate-content-delivery-request.json @@ -1942,7 +1942,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.375Z", + "generatedAt": "2026-04-22T04:00:56.673Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/validate-content-delivery-response.json b/schemas/cache/bundled/content-standards/validate-content-delivery-response.json index 7999d940..0abd23ab 100644 --- a/schemas/cache/bundled/content-standards/validate-content-delivery-response.json +++ b/schemas/cache/bundled/content-standards/validate-content-delivery-response.json @@ -188,7 +188,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.377Z", + "generatedAt": "2026-04-22T04:00:56.674Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/core/tasks-get-request.json b/schemas/cache/bundled/core/tasks-get-request.json index 099e90f2..0d3eff60 100644 --- a/schemas/cache/bundled/core/tasks-get-request.json +++ b/schemas/cache/bundled/core/tasks-get-request.json @@ -53,7 +53,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.378Z", + "generatedAt": "2026-04-22T04:00:56.675Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/core/tasks-get-response.json b/schemas/cache/bundled/core/tasks-get-response.json index 2e0c36b6..69b12f1a 100644 --- a/schemas/cache/bundled/core/tasks-get-response.json +++ b/schemas/cache/bundled/core/tasks-get-response.json @@ -270,7 +270,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.378Z", + "generatedAt": "2026-04-22T04:00:56.676Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/core/tasks-list-request.json b/schemas/cache/bundled/core/tasks-list-request.json index 0b4988ed..1e6b1998 100644 --- a/schemas/cache/bundled/core/tasks-list-request.json +++ b/schemas/cache/bundled/core/tasks-list-request.json @@ -394,7 +394,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.379Z", + "generatedAt": "2026-04-22T04:00:56.677Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/core/tasks-list-response.json b/schemas/cache/bundled/core/tasks-list-response.json index 20364923..246e7f04 100644 --- a/schemas/cache/bundled/core/tasks-list-response.json +++ b/schemas/cache/bundled/core/tasks-list-response.json @@ -251,7 +251,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.380Z", + "generatedAt": "2026-04-22T04:00:56.678Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/get-creative-delivery-request.json b/schemas/cache/bundled/creative/get-creative-delivery-request.json index cf2aae27..16288128 100644 --- a/schemas/cache/bundled/creative/get-creative-delivery-request.json +++ b/schemas/cache/bundled/creative/get-creative-delivery-request.json @@ -238,7 +238,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.380Z", + "generatedAt": "2026-04-22T04:00:56.678Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/get-creative-delivery-response.json b/schemas/cache/bundled/creative/get-creative-delivery-response.json index 439b1b67..9a8129af 100644 --- a/schemas/cache/bundled/creative/get-creative-delivery-response.json +++ b/schemas/cache/bundled/creative/get-creative-delivery-response.json @@ -1050,15 +1050,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1369,6 +1374,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -1380,6 +1386,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1846,6 +1857,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -1857,6 +1869,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -2208,6 +2225,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2215,773 +2233,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -3276,6 +2950,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3285,10 +2960,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -3590,6 +3270,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -3599,6 +3280,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -3916,6 +3602,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3925,6 +3612,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -4248,6 +3940,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4257,6 +3950,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -4282,7 +3980,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -4441,7 +4139,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -4921,6 +4619,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -4932,6 +4631,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -5226,6 +4930,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5233,371 +4938,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -5607,363 +5320,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5989,6 +5368,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5996,6 +5376,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -6189,6 +5580,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -6662,7 +6064,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -7384,7 +6789,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.394Z", + "generatedAt": "2026-04-22T04:00:56.690Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/get-creative-features-request.json b/schemas/cache/bundled/creative/get-creative-features-request.json index 83548fbc..c884b325 100644 --- a/schemas/cache/bundled/creative/get-creative-features-request.json +++ b/schemas/cache/bundled/creative/get-creative-features-request.json @@ -63,15 +63,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -382,6 +387,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -393,6 +399,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -859,6 +870,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -870,6 +882,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1221,6 +1238,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -1228,773 +1246,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -2289,6 +1963,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2298,10 +1973,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -2603,6 +2283,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2612,6 +2293,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -2929,6 +2615,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2938,6 +2625,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -3261,6 +2953,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3270,6 +2963,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3295,7 +2993,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3454,7 +3152,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3934,6 +3632,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -3945,6 +3644,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -4239,6 +3943,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4246,371 +3951,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -4620,363 +4333,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5002,6 +4381,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5009,6 +4389,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -5202,6 +4593,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -5675,7 +5077,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -6344,7 +5749,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.412Z", + "generatedAt": "2026-04-22T04:00:56.703Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/get-creative-features-response.json b/schemas/cache/bundled/creative/get-creative-features-response.json index 75b976e0..250bed46 100644 --- a/schemas/cache/bundled/creative/get-creative-features-response.json +++ b/schemas/cache/bundled/creative/get-creative-features-response.json @@ -223,7 +223,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.417Z", + "generatedAt": "2026-04-22T04:00:56.707Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/list-creative-formats-request.json b/schemas/cache/bundled/creative/list-creative-formats-request.json index 8cfa05e1..6730e008 100644 --- a/schemas/cache/bundled/creative/list-creative-formats-request.json +++ b/schemas/cache/bundled/creative/list-creative-formats-request.json @@ -478,7 +478,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.418Z", + "generatedAt": "2026-04-22T04:00:56.708Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/list-creative-formats-response.json b/schemas/cache/bundled/creative/list-creative-formats-response.json index 119bb3d2..dfc3182a 100644 --- a/schemas/cache/bundled/creative/list-creative-formats-response.json +++ b/schemas/cache/bundled/creative/list-creative-formats-response.json @@ -4093,7 +4093,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.423Z", + "generatedAt": "2026-04-22T04:00:56.713Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/list-creatives-request.json b/schemas/cache/bundled/creative/list-creatives-request.json index 9d613d70..1320fc69 100644 --- a/schemas/cache/bundled/creative/list-creatives-request.json +++ b/schemas/cache/bundled/creative/list-creatives-request.json @@ -680,7 +680,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.426Z", + "generatedAt": "2026-04-22T04:00:56.716Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/list-creatives-response.json b/schemas/cache/bundled/creative/list-creatives-response.json index 92ed0231..52d651c9 100644 --- a/schemas/cache/bundled/creative/list-creatives-response.json +++ b/schemas/cache/bundled/creative/list-creatives-response.json @@ -838,15 +838,20 @@ }, "assets": { "type": "object", - "description": "Assets for this creative, keyed by asset_id", + "description": "Assets for this creative, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1157,6 +1162,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -1168,6 +1174,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1634,6 +1645,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -1645,6 +1657,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1996,6 +2013,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2003,773 +2021,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -3064,6 +2738,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3073,10 +2748,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -3378,6 +3058,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -3387,6 +3068,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -3704,6 +3390,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3713,6 +3400,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -4036,6 +3728,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4045,6 +3738,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -4070,7 +3768,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -4229,7 +3927,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -4709,6 +4407,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -4720,6 +4419,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -5014,6 +4718,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5021,371 +4726,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -5395,363 +5108,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5777,6 +5156,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5784,6 +5164,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -5977,6 +5368,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -6450,7 +5852,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -7075,11 +6480,13 @@ "updated_date": "2026-02-20T09:30:00Z", "assets": { "banner_image": { + "asset_type": "image", "url": "https://cdn.example.com/holiday_300x250.png", "width": 300, "height": 250 }, "clickthrough_url": { + "asset_type": "url", "url": "https://acmecorp.example.com/holiday-sale" } }, @@ -7119,11 +6526,13 @@ "updated_date": "2026-02-20T09:35:00Z", "assets": { "banner_image": { + "asset_type": "image", "url": "https://cdn.example.com/holiday_728x90.png", "width": 728, "height": 90 }, "clickthrough_url": { + "asset_type": "url", "url": "https://acmecorp.example.com/holiday-sale" } }, @@ -7150,7 +6559,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.435Z", + "generatedAt": "2026-04-22T04:00:56.724Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/preview-creative-request.json b/schemas/cache/bundled/creative/preview-creative-request.json index 0f4baa2a..f582a3f7 100644 --- a/schemas/cache/bundled/creative/preview-creative-request.json +++ b/schemas/cache/bundled/creative/preview-creative-request.json @@ -72,15 +72,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -391,6 +396,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -402,6 +408,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -868,6 +879,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -879,6 +891,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1230,6 +1247,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -1237,389 +1255,397 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "jurisdictions": { + "type": "array", + "description": "Jurisdictions where disclosure obligations apply", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" + }, + "region": { + "type": "string", + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + }, + "regulation": { + "type": "string", + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + }, + "label_text": { + "type": "string", + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -1629,434 +1655,82 @@ "content": { "type": "string", "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + } + }, + "required": [ + "delivery_type", + "content" + ] + } + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true + }, + { + "title": "Text Asset", + "description": "Text content asset", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, + "content": { + "type": "string", + "description": "Text content" + }, + "language": { + "type": "string", + "description": "Language code (e.g., 'en', 'es', 'fr')" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "ai_tool": { "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "name": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "content" - ], - "additionalProperties": true - } - ] - }, - { - "title": "Text Asset", - "description": "Text content asset", - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Text content" - }, - "language": { - "type": "string", - "description": "Language code (e.g., 'en', 'es', 'fr')" - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { + "provider": { "type": "string", "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" } @@ -2298,6 +1972,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2307,10 +1982,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -2612,6 +2292,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2621,6 +2302,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -2938,6 +2624,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2947,6 +2634,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -3270,6 +2962,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3279,6 +2972,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3304,7 +3002,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3463,7 +3161,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3943,6 +3641,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -3954,6 +3653,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -4248,6 +3952,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4255,371 +3960,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "ai_tool": { "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "name": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } + }, + "required": [ + "name" + ], + "additionalProperties": true + }, + "human_oversight": { + "type": "string", + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } + }, + "declared_by": { + "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], "additionalProperties": true - } - }, - "required": [ + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, + "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -4629,363 +4342,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5011,6 +4390,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5018,6 +4398,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -5211,6 +4602,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -5684,7 +5086,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -6390,15 +5795,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -6709,6 +6119,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -6720,6 +6131,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -7186,6 +6602,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -7197,6 +6614,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -7548,6 +6970,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -7555,389 +6978,397 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "country", + "regulation" + ], + "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -7947,466 +7378,114 @@ "content": { "type": "string", "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + } + }, + "required": [ + "delivery_type", + "content" + ] + } + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true + }, + { + "title": "Text Asset", + "description": "Text content asset", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, + "content": { + "type": "string", + "description": "Text content" + }, + "language": { + "type": "string", + "description": "Language code (e.g., 'en', 'es', 'fr')" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "content" - ], - "additionalProperties": true - } - ] - }, - { - "title": "Text Asset", - "description": "Text content asset", - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Text content" - }, - "language": { - "type": "string", - "description": "Language code (e.g., 'en', 'es', 'fr')" - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { + "agent_url": { "type": "string", "format": "uri", "description": "URL of the agent or service that declared this provenance" @@ -8616,6 +7695,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -8625,10 +7705,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -8930,6 +8015,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -8939,6 +8025,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -9256,6 +8347,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -9265,6 +8357,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -9588,6 +8685,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -9597,6 +8695,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -9622,7 +8725,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -9781,7 +8884,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -9966,14 +9069,325 @@ "type": "string", "description": "Header name for HMAC signature (e.g., 'X-Signature')" }, - "api_key_header": { - "type": "string", - "description": "Header name for API key (e.g., 'X-API-Key')" + "api_key_header": { + "type": "string", + "description": "Header name for API key (e.g., 'X-API-Key')" + } + }, + "required": [ + "method" + ] + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", + "type": "string", + "enum": [ + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } + }, + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } + }, + "required": [ + "name" + ], + "additionalProperties": true + }, + "human_oversight": { + "type": "string", + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } + }, + "declared_by": { + "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent or service that declared this provenance" + }, + "role": { + "type": "string", + "enum": [ + "creator", + "advertiser", + "agency", + "platform", + "tool" + ], + "description": "Role of the declaring party in the supply chain", + "enumDescriptions": { + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" + } + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { + "type": "string", + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" + }, + "jurisdictions": { + "type": "array", + "description": "Jurisdictions where disclosure obligations apply", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" + }, + "region": { + "type": "string", + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + }, + "regulation": { + "type": "string", + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + }, + "label_text": { + "type": "string", + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "country", + "regulation" + ], + "additionalProperties": true + }, + "minItems": 1 + } + }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true } }, - "required": [ - "method" - ] + "additionalProperties": true + } + }, + "required": [ + "asset_type", + "url", + "response_type", + "security" + ], + "additionalProperties": true + }, + { + "title": "CSS Asset", + "description": "CSS stylesheet asset", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, + "content": { + "type": "string", + "description": "CSS content" + }, + "media": { + "type": "string", + "description": "CSS media query context (e.g., 'screen', 'print')" }, "provenance": { "title": "Provenance", @@ -10261,24 +9675,78 @@ } }, "required": [ - "url", - "response_type", - "security" + "asset_type", + "content" ], "additionalProperties": true }, { - "title": "CSS Asset", - "description": "CSS stylesheet asset", + "title": "DAAST Asset", + "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", "type": "object", "properties": { - "content": { + "asset_type": { "type": "string", - "description": "CSS content" + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." }, - "media": { + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", "type": "string", - "description": "CSS media query context (e.g., 'screen', 'print')" + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true }, "provenance": { "title": "Provenance", @@ -10497,447 +9965,97 @@ } }, "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "content" - ], - "additionalProperties": true - }, - { - "title": "DAAST Asset", - "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -10947,363 +10065,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -11329,6 +10113,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -11336,6 +10121,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -11529,6 +10325,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -12002,7 +10809,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -12637,7 +11447,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.454Z", + "generatedAt": "2026-04-22T04:00:56.741Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/preview-creative-response.json b/schemas/cache/bundled/creative/preview-creative-response.json index 0dff2969..880d17f1 100644 --- a/schemas/cache/bundled/creative/preview-creative-response.json +++ b/schemas/cache/bundled/creative/preview-creative-response.json @@ -1051,15 +1051,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1370,6 +1375,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -1381,6 +1387,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1847,6 +1858,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -1858,6 +1870,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -2209,6 +2226,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2216,773 +2234,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -3277,6 +2951,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3286,10 +2961,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -3591,6 +3271,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -3600,6 +3281,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -3917,6 +3603,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3926,7 +3613,12 @@ "description": "JavaScript code asset", "type": "object", "properties": { - "content": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, + "content": { "type": "string", "description": "JavaScript content" }, @@ -4249,6 +3941,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4258,6 +3951,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -4283,7 +3981,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -4442,7 +4140,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -4922,6 +4620,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -4933,13 +4632,377 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" }, - "media": { + "media": { + "type": "string", + "description": "CSS media query context (e.g., 'screen', 'print')" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", + "type": "string", + "enum": [ + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } + }, + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } + }, + "required": [ + "name" + ], + "additionalProperties": true + }, + "human_oversight": { + "type": "string", + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } + }, + "declared_by": { + "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent or service that declared this provenance" + }, + "role": { + "type": "string", + "enum": [ + "creator", + "advertiser", + "agency", + "platform", + "tool" + ], + "description": "Role of the declaring party in the supply chain", + "enumDescriptions": { + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" + } + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { + "type": "string", + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" + }, + "jurisdictions": { + "type": "array", + "description": "Jurisdictions where disclosure obligations apply", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" + }, + "region": { + "type": "string", + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + }, + "regulation": { + "type": "string", + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + }, + "label_text": { + "type": "string", + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "country", + "regulation" + ], + "additionalProperties": true + }, + "minItems": 1 + } + }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "asset_type", + "content" + ], + "additionalProperties": true + }, + { + "title": "DAAST Asset", + "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { "type": "string", - "description": "CSS media query context (e.g., 'screen', 'print')" + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true }, "provenance": { "title": "Provenance", @@ -5227,16 +5290,10 @@ } }, "required": [ - "content" + "asset_type" ], - "additionalProperties": true - }, - { - "title": "DAAST Asset", - "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", "oneOf": [ { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -5247,358 +5304,14 @@ "type": "string", "format": "uri", "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -5608,363 +5321,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5990,6 +5369,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5997,6 +5377,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -6190,6 +5581,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -6663,7 +6065,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -7184,7 +6589,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.469Z", + "generatedAt": "2026-04-22T04:00:56.754Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/sync-creatives-request.json b/schemas/cache/bundled/creative/sync-creatives-request.json index dce4105d..1f75d724 100644 --- a/schemas/cache/bundled/creative/sync-creatives-request.json +++ b/schemas/cache/bundled/creative/sync-creatives-request.json @@ -225,15 +225,20 @@ }, "assets": { "type": "object", - "description": "Assets required by the format, keyed by asset_id", + "description": "Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -544,6 +549,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -555,6 +561,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1021,6 +1032,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -1032,6 +1044,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1383,6 +1400,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -1390,773 +1408,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -2451,6 +2125,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2460,10 +2135,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -2765,6 +2445,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2774,6 +2455,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -3091,6 +2777,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3100,6 +2787,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -3423,6 +3115,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3432,6 +3125,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3457,7 +3155,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3616,7 +3314,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -4096,6 +3794,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -4107,6 +3806,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -4401,6 +4105,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4408,371 +4113,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -4782,363 +4495,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5164,6 +4543,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5171,6 +4551,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -5364,6 +4755,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -5837,7 +5239,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -6412,6 +5817,7 @@ }, "assets": { "video": { + "asset_type": "video", "url": "https://cdn.example.com/hero-video.mp4", "width": 1920, "height": 1080, @@ -6453,10 +5859,12 @@ }, "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" } }, @@ -6489,6 +5897,7 @@ }, "assets": { "video": { + "asset_type": "video", "url": "https://cdn.example.com/updated-hero.mp4", "width": 1920, "height": 1080, @@ -6505,6 +5914,7 @@ }, "assets": { "image": { + "asset_type": "image", "url": "https://cdn.example.com/updated-banner.png", "width": 300, "height": 250 @@ -6516,7 +5926,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.480Z", + "generatedAt": "2026-04-22T04:00:56.763Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/creative/sync-creatives-response.json b/schemas/cache/bundled/creative/sync-creatives-response.json index fef025b2..ff8533fa 100644 --- a/schemas/cache/bundled/creative/sync-creatives-response.json +++ b/schemas/cache/bundled/creative/sync-creatives-response.json @@ -1117,7 +1117,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.483Z", + "generatedAt": "2026-04-22T04:00:56.766Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/build-creative-request.json b/schemas/cache/bundled/media-buy/build-creative-request.json index 7d2d2d35..2a6403f0 100644 --- a/schemas/cache/bundled/media-buy/build-creative-request.json +++ b/schemas/cache/bundled/media-buy/build-creative-request.json @@ -68,15 +68,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -387,6 +392,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -398,6 +404,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -864,6 +875,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -875,6 +887,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1226,6 +1243,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -1233,773 +1251,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -2294,6 +1968,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2303,10 +1978,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -2608,6 +2288,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2617,6 +2298,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -2934,6 +2620,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2943,6 +2630,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -3266,6 +2958,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3275,6 +2968,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3300,7 +2998,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3459,7 +3157,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3939,6 +3637,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -3950,6 +3649,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -4244,6 +3948,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4251,371 +3956,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -4625,363 +4338,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5007,6 +4386,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5014,6 +4394,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -5207,6 +4598,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -5680,7 +5082,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -6629,7 +6034,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.491Z", + "generatedAt": "2026-04-22T04:00:56.773Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/build-creative-response.json b/schemas/cache/bundled/media-buy/build-creative-response.json index 3f0a0d5a..39f6d1e9 100644 --- a/schemas/cache/bundled/media-buy/build-creative-response.json +++ b/schemas/cache/bundled/media-buy/build-creative-response.json @@ -62,15 +62,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -381,6 +386,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -392,6 +398,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -858,6 +869,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -869,6 +881,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -1220,6 +1237,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -1227,389 +1245,397 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "jurisdictions": { + "type": "array", + "description": "Jurisdictions where disclosure obligations apply", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" + }, + "region": { + "type": "string", + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + }, + "regulation": { + "type": "string", + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + }, + "label_text": { + "type": "string", + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -1619,428 +1645,76 @@ "content": { "type": "string", "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + } + }, + "required": [ + "delivery_type", + "content" + ] + } + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true + }, + { + "title": "Text Asset", + "description": "Text content asset", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, + "content": { + "type": "string", + "description": "Text content" + }, + "language": { + "type": "string", + "description": "Language code (e.g., 'en', 'es', 'fr')" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "ai_tool": { "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "name": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "content" - ], - "additionalProperties": true - } - ] - }, - { - "title": "Text Asset", - "description": "Text content asset", - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Text content" - }, - "language": { - "type": "string", - "description": "Language code (e.g., 'en', 'es', 'fr')" - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" }, "version": { "type": "string", @@ -2288,6 +1962,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2297,10 +1972,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -2602,6 +2282,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -2611,6 +2292,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -2928,6 +2614,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -2937,6 +2624,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -3260,6 +2952,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -3269,6 +2962,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3294,7 +2992,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3453,7 +3151,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -3933,6 +3631,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -3944,6 +3643,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -4238,6 +3942,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4245,371 +3950,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "transcript_url": { + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } + }, + "required": [ + "name" + ], + "additionalProperties": true + }, + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, - "additionalProperties": true + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -4619,363 +4332,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -5001,6 +4380,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5008,6 +4388,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -5201,6 +4592,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -5674,7 +5076,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -6640,15 +6045,20 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -6959,6 +6369,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -6970,6 +6381,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -7436,6 +6852,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -7447,6 +6864,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -7798,6 +7220,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -7805,389 +7228,397 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -8197,432 +7628,80 @@ "content": { "type": "string", "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + } + }, + "required": [ + "delivery_type", + "content" + ] + } + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true + }, + { + "title": "Text Asset", + "description": "Text content asset", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, + "content": { + "type": "string", + "description": "Text content" + }, + "language": { + "type": "string", + "description": "Language code (e.g., 'en', 'es', 'fr')" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "ai_tool": { "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "name": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" }, - "human_oversight": { + "version": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "content" - ], - "additionalProperties": true - } - ] - }, - { - "title": "Text Asset", - "description": "Text content asset", - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Text content" - }, - "language": { - "type": "string", - "description": "Language code (e.g., 'en', 'es', 'fr')" - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." }, "provider": { "type": "string", @@ -8866,6 +7945,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -8875,10 +7955,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -9180,6 +8265,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -9189,6 +8275,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -9506,6 +8597,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -9515,6 +8607,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -9838,6 +8935,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -9847,6 +8945,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -9872,7 +8975,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -10031,7 +9134,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -10511,24 +9614,389 @@ } }, "required": [ - "url", - "response_type", - "security" + "asset_type", + "url", + "response_type", + "security" + ], + "additionalProperties": true + }, + { + "title": "CSS Asset", + "description": "CSS stylesheet asset", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, + "content": { + "type": "string", + "description": "CSS content" + }, + "media": { + "type": "string", + "description": "CSS media query context (e.g., 'screen', 'print')" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", + "type": "string", + "enum": [ + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } + }, + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } + }, + "required": [ + "name" + ], + "additionalProperties": true + }, + "human_oversight": { + "type": "string", + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } + }, + "declared_by": { + "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent or service that declared this provenance" + }, + "role": { + "type": "string", + "enum": [ + "creator", + "advertiser", + "agency", + "platform", + "tool" + ], + "description": "Role of the declaring party in the supply chain", + "enumDescriptions": { + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" + } + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { + "type": "string", + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" + }, + "jurisdictions": { + "type": "array", + "description": "Jurisdictions where disclosure obligations apply", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" + }, + "region": { + "type": "string", + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + }, + "regulation": { + "type": "string", + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + }, + "label_text": { + "type": "string", + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "country", + "regulation" + ], + "additionalProperties": true + }, + "minItems": 1 + } + }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "asset_type", + "content" ], "additionalProperties": true }, { - "title": "CSS Asset", - "description": "CSS stylesheet asset", + "title": "DAAST Asset", + "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", "type": "object", "properties": { - "content": { + "asset_type": { "type": "string", - "description": "CSS content" + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." }, - "media": { + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", "type": "string", - "description": "CSS media query context (e.g., 'screen', 'print')" + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true }, "provenance": { "title": "Provenance", @@ -10738,456 +10206,106 @@ }, "ext": { "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "content" - ], - "additionalProperties": true - }, - { - "title": "DAAST Asset", - "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -11197,363 +10315,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -11579,6 +10363,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -11586,6 +10371,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -11779,6 +10575,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -12252,7 +11059,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -13288,7 +12098,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.508Z", + "generatedAt": "2026-04-22T04:00:56.788Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/create-media-buy-request.json b/schemas/cache/bundled/media-buy/create-media-buy-request.json index 3b39332c..b9d800d8 100644 --- a/schemas/cache/bundled/media-buy/create-media-buy-request.json +++ b/schemas/cache/bundled/media-buy/create-media-buy-request.json @@ -2519,15 +2519,20 @@ }, "assets": { "type": "object", - "description": "Assets required by the format, keyed by asset_id", + "description": "Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -2838,6 +2843,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -2849,6 +2855,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3315,6 +3326,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -3326,6 +3338,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3677,6 +3694,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -3684,773 +3702,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -4745,6 +4419,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4754,10 +4429,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -5059,6 +4739,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -5068,6 +4749,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -5385,6 +5071,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5394,6 +5081,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -5717,6 +5409,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5726,6 +5419,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -5751,7 +5449,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -5910,7 +5608,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -6390,6 +6088,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -6401,6 +6100,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -6695,6 +6399,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -6702,371 +6407,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -7076,363 +6789,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -7458,6 +6837,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -7465,6 +6845,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -7658,6 +7049,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -8131,7 +7533,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -9346,7 +8751,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.528Z", + "generatedAt": "2026-04-22T04:00:56.803Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/create-media-buy-response.json b/schemas/cache/bundled/media-buy/create-media-buy-response.json index c04b545a..d44ed002 100644 --- a/schemas/cache/bundled/media-buy/create-media-buy-response.json +++ b/schemas/cache/bundled/media-buy/create-media-buy-response.json @@ -4246,7 +4246,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.536Z", + "generatedAt": "2026-04-22T04:00:56.813Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/get-media-buy-delivery-request.json b/schemas/cache/bundled/media-buy/get-media-buy-delivery-request.json index 84f02143..ee65f7be 100644 --- a/schemas/cache/bundled/media-buy/get-media-buy-delivery-request.json +++ b/schemas/cache/bundled/media-buy/get-media-buy-delivery-request.json @@ -607,7 +607,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.538Z", + "generatedAt": "2026-04-22T04:00:56.816Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/get-media-buy-delivery-response.json b/schemas/cache/bundled/media-buy/get-media-buy-delivery-response.json index 2a257c45..76a9cc7b 100644 --- a/schemas/cache/bundled/media-buy/get-media-buy-delivery-response.json +++ b/schemas/cache/bundled/media-buy/get-media-buy-delivery-response.json @@ -5294,7 +5294,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.544Z", + "generatedAt": "2026-04-22T04:00:56.820Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/get-media-buys-request.json b/schemas/cache/bundled/media-buy/get-media-buys-request.json index ba023f26..9f817cb1 100644 --- a/schemas/cache/bundled/media-buy/get-media-buys-request.json +++ b/schemas/cache/bundled/media-buy/get-media-buys-request.json @@ -269,7 +269,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.547Z", + "generatedAt": "2026-04-22T04:00:56.822Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/get-media-buys-response.json b/schemas/cache/bundled/media-buy/get-media-buys-response.json index 52d4a2ca..e8c1a3b7 100644 --- a/schemas/cache/bundled/media-buy/get-media-buys-response.json +++ b/schemas/cache/bundled/media-buy/get-media-buys-response.json @@ -2342,7 +2342,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.550Z", + "generatedAt": "2026-04-22T04:00:56.825Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/get-products-request.json b/schemas/cache/bundled/media-buy/get-products-request.json index 678af3be..3f8e394a 100644 --- a/schemas/cache/bundled/media-buy/get-products-request.json +++ b/schemas/cache/bundled/media-buy/get-products-request.json @@ -29,6 +29,9 @@ "minItems": 1, "items": { "type": "object", + "discriminator": { + "propertyName": "scope" + }, "oneOf": [ { "properties": { @@ -56,7 +59,7 @@ "const": "product", "description": "Change scoped to a specific product." }, - "id": { + "product_id": { "type": "string", "minLength": 1, "description": "Product ID from a previous get_products response." @@ -68,7 +71,8 @@ "omit", "more_like_this" ], - "description": "'include': return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned)." + "default": "include", + "description": "'include' (default): return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned). Optional \u2014 when omitted, the seller treats the entry as action: 'include'." }, "ask": { "type": "string", @@ -78,8 +82,7 @@ }, "required": [ "scope", - "id", - "action" + "product_id" ], "additionalProperties": false }, @@ -90,7 +93,7 @@ "const": "proposal", "description": "Change scoped to a specific proposal." }, - "id": { + "proposal_id": { "type": "string", "minLength": 1, "description": "Proposal ID from a previous get_products response." @@ -102,7 +105,8 @@ "omit", "finalize" ], - "description": "'include': return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold \u2014 transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests \u2014 they represent a commitment to wait for the result." + "default": "include", + "description": "'include' (default): return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold \u2014 transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests \u2014 they represent a commitment to wait for the result. Optional \u2014 when omitted, the seller treats the entry as action: 'include'." }, "ask": { "type": "string", @@ -112,8 +116,7 @@ }, "required": [ "scope", - "id", - "action" + "proposal_id" ], "additionalProperties": false } @@ -2030,7 +2033,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.555Z", + "generatedAt": "2026-04-22T04:00:56.829Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/get-products-response.json b/schemas/cache/bundled/media-buy/get-products-response.json index c4455946..a143a1cb 100644 --- a/schemas/cache/bundled/media-buy/get-products-response.json +++ b/schemas/cache/bundled/media-buy/get-products-response.json @@ -7111,41 +7111,105 @@ }, "refinement_applied": { "type": "array", - "description": "Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'.", + "description": "Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'. Each entry MUST echo the request entry's scope and \u2014 for product and proposal scopes \u2014 the matching id field (product_id or proposal_id), so orchestrators can cross-validate alignment.", "items": { "type": "object", - "properties": { - "scope": { - "type": "string", - "enum": [ - "request", - "product", - "proposal" + "discriminator": { + "propertyName": "scope" + }, + "oneOf": [ + { + "properties": { + "scope": { + "type": "string", + "const": "request", + "description": "Echoes scope 'request' from the corresponding refine entry." + }, + "status": { + "type": "string", + "enum": [ + "applied", + "partial", + "unable" + ], + "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + }, + "notes": { + "type": "string", + "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + } + }, + "required": [ + "scope", + "status" ], - "description": "Echoes the scope from the corresponding refine entry. Allows orchestrators to cross-validate alignment." - }, - "id": { - "type": "string", - "description": "Echoes the id from the corresponding refine entry (for product and proposal scopes)." + "additionalProperties": false }, - "status": { - "type": "string", - "enum": [ - "applied", - "partial", - "unable" + { + "properties": { + "scope": { + "type": "string", + "const": "product", + "description": "Echoes scope 'product' from the corresponding refine entry." + }, + "product_id": { + "type": "string", + "description": "Echoes product_id from the corresponding refine entry." + }, + "status": { + "type": "string", + "enum": [ + "applied", + "partial", + "unable" + ], + "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + }, + "notes": { + "type": "string", + "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + } + }, + "required": [ + "scope", + "product_id", + "status" ], - "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + "additionalProperties": false }, - "notes": { - "type": "string", - "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + { + "properties": { + "scope": { + "type": "string", + "const": "proposal", + "description": "Echoes scope 'proposal' from the corresponding refine entry." + }, + "proposal_id": { + "type": "string", + "description": "Echoes proposal_id from the corresponding refine entry." + }, + "status": { + "type": "string", + "enum": [ + "applied", + "partial", + "unable" + ], + "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + }, + "notes": { + "type": "string", + "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + } + }, + "required": [ + "scope", + "proposal_id", + "status" + ], + "additionalProperties": false } - }, - "required": [ - "status" - ], - "additionalProperties": false + ] } }, "incomplete": { @@ -7256,7 +7320,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.563Z", + "generatedAt": "2026-04-22T04:00:56.840Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/list-creative-formats-request.json b/schemas/cache/bundled/media-buy/list-creative-formats-request.json index 1af361d7..1557790a 100644 --- a/schemas/cache/bundled/media-buy/list-creative-formats-request.json +++ b/schemas/cache/bundled/media-buy/list-creative-formats-request.json @@ -304,7 +304,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.566Z", + "generatedAt": "2026-04-22T04:00:56.843Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/list-creative-formats-response.json b/schemas/cache/bundled/media-buy/list-creative-formats-response.json index 9b0c8f22..8fe290bb 100644 --- a/schemas/cache/bundled/media-buy/list-creative-formats-response.json +++ b/schemas/cache/bundled/media-buy/list-creative-formats-response.json @@ -4097,7 +4097,7 @@ } }, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.570Z", + "generatedAt": "2026-04-22T04:00:56.847Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/log-event-request.json b/schemas/cache/bundled/media-buy/log-event-request.json index 681f93f4..adcda528 100644 --- a/schemas/cache/bundled/media-buy/log-event-request.json +++ b/schemas/cache/bundled/media-buy/log-event-request.json @@ -387,7 +387,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.573Z", + "generatedAt": "2026-04-22T04:00:56.849Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/log-event-response.json b/schemas/cache/bundled/media-buy/log-event-response.json index c3042fce..2022ca98 100644 --- a/schemas/cache/bundled/media-buy/log-event-response.json +++ b/schemas/cache/bundled/media-buy/log-event-response.json @@ -186,7 +186,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.573Z", + "generatedAt": "2026-04-22T04:00:56.850Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/package-request.json b/schemas/cache/bundled/media-buy/package-request.json index bcf32d6e..7b33ceda 100644 --- a/schemas/cache/bundled/media-buy/package-request.json +++ b/schemas/cache/bundled/media-buy/package-request.json @@ -2319,15 +2319,20 @@ }, "assets": { "type": "object", - "description": "Assets required by the format, keyed by asset_id", + "description": "Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -2638,6 +2643,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -2649,6 +2655,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3115,6 +3126,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -3126,6 +3138,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3477,6 +3494,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -3484,773 +3502,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -4545,6 +4219,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4554,10 +4229,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -4859,6 +4539,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -4868,6 +4549,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -5185,6 +4871,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5194,6 +4881,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -5517,6 +5209,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5526,6 +5219,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -5551,7 +5249,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -5710,7 +5408,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -6190,6 +5888,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -6201,6 +5900,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -6495,6 +6199,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -6502,371 +6207,379 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -6876,363 +6589,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -7258,6 +6637,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -7265,6 +6645,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -7458,6 +6849,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -7931,7 +7333,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -8367,7 +7772,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.583Z", + "generatedAt": "2026-04-22T04:00:56.859Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/provide-performance-feedback-request.json b/schemas/cache/bundled/media-buy/provide-performance-feedback-request.json index 384762b7..ccdd6fd9 100644 --- a/schemas/cache/bundled/media-buy/provide-performance-feedback-request.json +++ b/schemas/cache/bundled/media-buy/provide-performance-feedback-request.json @@ -112,7 +112,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.586Z", + "generatedAt": "2026-04-22T04:00:56.862Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/provide-performance-feedback-response.json b/schemas/cache/bundled/media-buy/provide-performance-feedback-response.json index e9998afd..7ccefcb5 100644 --- a/schemas/cache/bundled/media-buy/provide-performance-feedback-response.json +++ b/schemas/cache/bundled/media-buy/provide-performance-feedback-response.json @@ -135,7 +135,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.586Z", + "generatedAt": "2026-04-22T04:00:56.862Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/sync-audiences-request.json b/schemas/cache/bundled/media-buy/sync-audiences-request.json index d01130b2..8bcd22ca 100644 --- a/schemas/cache/bundled/media-buy/sync-audiences-request.json +++ b/schemas/cache/bundled/media-buy/sync-audiences-request.json @@ -468,7 +468,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.587Z", + "generatedAt": "2026-04-22T04:00:56.863Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/sync-audiences-response.json b/schemas/cache/bundled/media-buy/sync-audiences-response.json index e00773b3..ef07e088 100644 --- a/schemas/cache/bundled/media-buy/sync-audiences-response.json +++ b/schemas/cache/bundled/media-buy/sync-audiences-response.json @@ -322,7 +322,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.588Z", + "generatedAt": "2026-04-22T04:00:56.864Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/sync-catalogs-request.json b/schemas/cache/bundled/media-buy/sync-catalogs-request.json index a2e76209..d5614797 100644 --- a/schemas/cache/bundled/media-buy/sync-catalogs-request.json +++ b/schemas/cache/bundled/media-buy/sync-catalogs-request.json @@ -829,7 +829,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.589Z", + "generatedAt": "2026-04-22T04:00:56.865Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/sync-catalogs-response.json b/schemas/cache/bundled/media-buy/sync-catalogs-response.json index 4c56401b..06b37a55 100644 --- a/schemas/cache/bundled/media-buy/sync-catalogs-response.json +++ b/schemas/cache/bundled/media-buy/sync-catalogs-response.json @@ -337,7 +337,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.590Z", + "generatedAt": "2026-04-22T04:00:56.865Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/sync-event-sources-request.json b/schemas/cache/bundled/media-buy/sync-event-sources-request.json index 29e408cf..3adb6f71 100644 --- a/schemas/cache/bundled/media-buy/sync-event-sources-request.json +++ b/schemas/cache/bundled/media-buy/sync-event-sources-request.json @@ -292,7 +292,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.591Z", + "generatedAt": "2026-04-22T04:00:56.866Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/sync-event-sources-response.json b/schemas/cache/bundled/media-buy/sync-event-sources-response.json index 2769c4e0..22562817 100644 --- a/schemas/cache/bundled/media-buy/sync-event-sources-response.json +++ b/schemas/cache/bundled/media-buy/sync-event-sources-response.json @@ -454,7 +454,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.591Z", + "generatedAt": "2026-04-22T04:00:56.867Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/update-media-buy-request.json b/schemas/cache/bundled/media-buy/update-media-buy-request.json index b9a5bebc..81cdd8a6 100644 --- a/schemas/cache/bundled/media-buy/update-media-buy-request.json +++ b/schemas/cache/bundled/media-buy/update-media-buy-request.json @@ -2303,15 +2303,20 @@ }, "assets": { "type": "object", - "description": "Assets required by the format, keyed by asset_id", + "description": "Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -2622,6 +2627,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -2633,6 +2639,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3099,6 +3110,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -3110,6 +3122,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -3461,6 +3478,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -3468,773 +3486,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline VAST XML content" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", - "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -4529,6 +4203,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -4538,10 +4213,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -4843,6 +4523,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -4852,6 +4533,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -5169,6 +4855,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5178,6 +4865,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -5501,6 +5193,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -5510,6 +5203,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -5535,7 +5233,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -5694,7 +5392,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -6174,6 +5872,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" @@ -6185,6 +5884,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -6479,6 +6183,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -6486,737 +6191,411 @@ { "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating DAAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" + "required": [ + "name" + ], + "additionalProperties": true }, - "transcript_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { + } + }, + "required": [ + "role" + ], + "additionalProperties": true + }, + "declared_at": { + "type": "string", + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." + }, + "created_time": { + "type": "string", + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating DAAST is delivered as inline XML content" - }, - "content": { - "type": "string", - "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true }, - "render_guidance": { + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, "additionalProperties": true } }, - "required": [ - "country", - "regulation" - ], "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating DAAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns DAAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating DAAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline DAAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -7242,6 +6621,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -7249,6 +6629,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -7442,6 +6833,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -7915,7 +7317,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -10877,15 +10282,20 @@ }, "assets": { "type": "object", - "description": "Assets required by the format, keyed by asset_id", + "description": "Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "title": "Image Asset", "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -11196,6 +10606,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -11207,6 +10618,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -11673,6 +11089,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" @@ -11684,6 +11101,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -12035,6 +11457,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -12042,773 +11465,429 @@ { "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", - "oneOf": [ - { + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "title": "VAST Version", + "description": "VAST specification version", + "type": "string", + "enum": [ + "2.0", + "3.0", + "4.0", + "4.1", + "4.2" + ] + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "VAST Tracking Event", + "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "rewind", + "skip", + "playerExpand", + "playerCollapse", + "fullscreen", + "exitFullscreen", + "progress", + "notUsed", + "otherAdInteraction", + "interactiveStart", + "clickTracking", + "customClick", + "close", + "closeLinear", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", "type": "object", "properties": { - "delivery_type": { - "type": "string", - "const": "url", - "description": "Discriminator indicating VAST is delivered via URL endpoint" - }, - "url": { - "type": "string", - "format": "uri", - "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", "type": "string", "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true + "required": [ + "name" + ], + "additionalProperties": true }, - "audio_description_url": { + "human_oversight": { "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "declared_by": { "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", + "agent_url": { "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true + "format": "uri", + "description": "URL of the agent or service that declared this provenance" }, - "human_oversight": { + "role": { "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" + "creator", + "advertiser", + "agency", + "platform", + "tool" ], + "description": "Role of the declaring party in the supply chain", "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true } }, + "required": [ + "role" + ], "additionalProperties": true - } - }, - "required": [ - "delivery_type", - "url" - ], - "additionalProperties": true - }, - { - "type": "object", - "properties": { - "delivery_type": { - "type": "string", - "const": "inline", - "description": "Discriminator indicating VAST is delivered as inline XML content" }, - "content": { + "declared_at": { "type": "string", - "description": "Inline VAST XML content" + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." }, - "vast_version": { - "title": "VAST Version", - "description": "VAST specification version", + "created_time": { "type": "string", - "enum": [ - "2.0", - "3.0", - "4.0", - "4.1", - "4.2" - ] - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" }, - "tracking_events": { - "type": "array", - "items": { - "title": "VAST Tracking Event", - "description": "Tracking events for video ads. Includes IAB VAST 4.2 TrackingEvents, plus flattened representations of Impression, Error, VideoClicks, and ViewableImpression elements. fullscreen/exitFullscreen retained for VAST 2.x/3.x compatibility. measurableImpression is an AdCP extension for MRC measurability signals.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "rewind", - "skip", - "playerExpand", - "playerCollapse", - "fullscreen", - "exitFullscreen", - "progress", - "notUsed", - "otherAdInteraction", - "interactiveStart", - "clickTracking", - "customClick", - "close", - "closeLinear", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { + "type": "string", + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true + "required": [ + "manifest_url" + ], + "additionalProperties": true }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "disclosure": { "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" }, - "verification": { + "jurisdictions": { "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, + "description": "Jurisdictions where disclosure obligations apply", "items": { "type": "object", "properties": { - "verified_by": { + "country": { "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" }, - "verified_time": { + "region": { "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" }, - "result": { + "regulation": { "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" }, - "details_url": { + "label_text": { "type": "string", - "format": "uri", - "description": "URL to the full verification report" + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } }, "required": [ - "verified_by", - "result" + "country", + "regulation" ], "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true + }, + "minItems": 1 } }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", "additionalProperties": true } }, + "additionalProperties": true + } + }, + "required": [ + "asset_type" + ], + "oneOf": [ + { + "properties": { + "delivery_type": { + "type": "string", + "const": "url", + "description": "Discriminator indicating VAST is delivered via URL endpoint" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL endpoint that returns VAST XML" + } + }, + "required": [ + "delivery_type", + "url" + ] + }, + { + "properties": { + "delivery_type": { + "type": "string", + "const": "inline", + "description": "Discriminator indicating VAST is delivered as inline XML content" + }, + "content": { + "type": "string", + "description": "Inline VAST XML content" + } + }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Text Asset", "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -13103,6 +12182,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -13112,10 +12192,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "title": "URL Asset Type", @@ -13417,6 +12502,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true @@ -13426,6 +12512,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -13743,6 +12834,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -13752,6 +12844,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -14075,6 +13172,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -14084,6 +13182,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -14109,7 +13212,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -14268,7 +13371,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "title": "Universal Macro", "description": "Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.", @@ -14416,51 +13519,362 @@ "APP_ITEM_ID": "Mobile app identifier for the catalog item being rendered" } }, - { - "type": "string", - "description": "Custom or publisher-specific macro name" - } - ] - }, - "description": "Universal macros that must be provided for webhook to function" - }, - "response_type": { - "title": "Webhook Response Type", - "description": "Expected content type of webhook response", - "type": "string", - "enum": [ - "html", - "json", - "xml", - "javascript" - ] - }, - "security": { - "type": "object", - "description": "Security configuration for webhook calls", - "properties": { - "method": { - "title": "Webhook Security Method", - "description": "Authentication method", - "type": "string", - "enum": [ - "hmac_sha256", - "api_key", - "none" - ] + { + "type": "string", + "description": "Custom or publisher-specific macro name" + } + ] + }, + "description": "Universal macros that must be provided for webhook to function" + }, + "response_type": { + "title": "Webhook Response Type", + "description": "Expected content type of webhook response", + "type": "string", + "enum": [ + "html", + "json", + "xml", + "javascript" + ] + }, + "security": { + "type": "object", + "description": "Security configuration for webhook calls", + "properties": { + "method": { + "title": "Webhook Security Method", + "description": "Authentication method", + "type": "string", + "enum": [ + "hmac_sha256", + "api_key", + "none" + ] + }, + "hmac_header": { + "type": "string", + "description": "Header name for HMAC signature (e.g., 'X-Signature')" + }, + "api_key_header": { + "type": "string", + "description": "Header name for API key (e.g., 'X-API-Key')" + } + }, + "required": [ + "method" + ] + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this asset, overrides manifest-level provenance", + "type": "object", + "properties": { + "digital_source_type": { + "title": "Digital Source Type", + "description": "IPTC-aligned classification of AI involvement in producing this content", + "type": "string", + "enum": [ + "digital_capture", + "digital_creation", + "trained_algorithmic_media", + "composite_with_trained_algorithmic_media", + "algorithmic_media", + "composite_capture", + "composite_synthetic", + "human_edits", + "data_driven_media" + ], + "enumDescriptions": { + "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", + "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", + "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", + "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", + "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", + "composite_capture": "Multiple digital captures composited together without AI", + "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", + "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", + "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" + } + }, + "ai_tool": { + "type": "object", + "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", + "properties": { + "name": { + "type": "string", + "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" + }, + "version": { + "type": "string", + "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." + }, + "provider": { + "type": "string", + "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" + } + }, + "required": [ + "name" + ], + "additionalProperties": true + }, + "human_oversight": { + "type": "string", + "description": "Level of human involvement in the AI-assisted creation process", + "enum": [ + "none", + "prompt_only", + "selected", + "edited", + "directed" + ], + "enumDescriptions": { + "none": "Fully automated with no human involvement in generation", + "prompt_only": "Human provided the prompt or instructions but did not review outputs", + "selected": "Human selected from multiple AI-generated candidates", + "edited": "Human edited or refined AI-generated output", + "directed": "Human directed the creative process with AI as an assistive tool" + } + }, + "declared_by": { + "type": "object", + "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent or service that declared this provenance" + }, + "role": { + "type": "string", + "enum": [ + "creator", + "advertiser", + "agency", + "platform", + "tool" + ], + "description": "Role of the declaring party in the supply chain", + "enumDescriptions": { + "creator": "The party that created or generated the content", + "advertiser": "The brand or advertiser that owns the content", + "agency": "Agency acting on behalf of the advertiser", + "platform": "Ad platform or publisher that processed the content", + "tool": "Automated tool or service that attached provenance metadata" + } + } + }, + "required": [ + "role" + ], + "additionalProperties": true }, - "hmac_header": { + "declared_at": { "type": "string", - "description": "Header name for HMAC signature (e.g., 'X-Signature')" + "format": "date-time", + "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." }, - "api_key_header": { + "created_time": { "type": "string", - "description": "Header name for API key (e.g., 'X-API-Key')" + "format": "date-time", + "description": "When this content was created or generated (ISO 8601)" + }, + "c2pa": { + "type": "object", + "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", + "properties": { + "manifest_url": { + "type": "string", + "format": "uri", + "description": "URL to the C2PA manifest store for this content" + } + }, + "required": [ + "manifest_url" + ], + "additionalProperties": true + }, + "disclosure": { + "type": "object", + "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", + "properties": { + "required": { + "type": "boolean", + "description": "Whether AI disclosure is required for this content based on applicable regulations" + }, + "jurisdictions": { + "type": "array", + "description": "Jurisdictions where disclosure obligations apply", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" + }, + "region": { + "type": "string", + "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" + }, + "regulation": { + "type": "string", + "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" + }, + "label_text": { + "type": "string", + "description": "Required disclosure label text for this jurisdiction, in the local language" + }, + "render_guidance": { + "type": "object", + "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", + "minProperties": 1, + "properties": { + "persistence": { + "title": "Disclosure Persistence", + "description": "How long the disclosure must persist during content playback or display", + "type": "string", + "enum": [ + "continuous", + "initial", + "flexible" + ], + "enumDescriptions": { + "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", + "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", + "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" + } + }, + "min_duration_ms": { + "type": "integer", + "minimum": 1, + "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." + }, + "positions": { + "type": "array", + "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", + "items": { + "title": "Disclosure Position", + "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", + "type": "string", + "enum": [ + "prominent", + "footer", + "audio", + "subtitle", + "overlay", + "end_card", + "pre_roll", + "companion" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "country", + "regulation" + ], + "additionalProperties": true + }, + "minItems": 1 + } + }, + "required": [ + "required" + ], + "additionalProperties": true + }, + "verification": { + "type": "array", + "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "verified_by": { + "type": "string", + "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" + }, + "verified_time": { + "type": "string", + "format": "date-time", + "description": "When the verification was performed (ISO 8601)" + }, + "result": { + "type": "string", + "enum": [ + "authentic", + "ai_generated", + "ai_modified", + "inconclusive" + ], + "description": "Verification outcome" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence score of the verification result (0.0 to 1.0)" + }, + "details_url": { + "type": "string", + "format": "uri", + "description": "URL to the full verification report" + } + }, + "required": [ + "verified_by", + "result" + ], + "additionalProperties": true + } + }, + "ext": { + "title": "Extension Object", + "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", + "type": "object", + "additionalProperties": true } }, - "required": [ - "method" - ] + "additionalProperties": true + } + }, + "required": [ + "asset_type", + "url", + "response_type", + "security" + ], + "additionalProperties": true + }, + { + "title": "CSS Asset", + "description": "CSS stylesheet asset", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, + "content": { + "type": "string", + "description": "CSS content" + }, + "media": { + "type": "string", + "description": "CSS media query context (e.g., 'screen', 'print')" }, "provenance": { "title": "Provenance", @@ -14748,24 +14162,78 @@ } }, "required": [ - "url", - "response_type", - "security" + "asset_type", + "content" ], "additionalProperties": true }, { - "title": "CSS Asset", - "description": "CSS stylesheet asset", + "title": "DAAST Asset", + "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", "type": "object", "properties": { - "content": { + "asset_type": { "type": "string", - "description": "CSS content" + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "title": "DAAST Version", + "description": "DAAST specification version", + "type": "string", + "enum": [ + "1.0", + "1.1" + ] }, - "media": { + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "title": "DAAST Tracking Event", + "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", + "type": "string", + "enum": [ + "impression", + "creativeView", + "loaded", + "start", + "firstQuartile", + "midpoint", + "thirdQuartile", + "complete", + "mute", + "unmute", + "pause", + "resume", + "skip", + "progress", + "clickTracking", + "customClick", + "close", + "error", + "viewable", + "notViewable", + "viewUndetermined", + "measurableImpression", + "viewableImpression" + ] + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { "type": "string", - "description": "CSS media query context (e.g., 'screen', 'print')" + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true }, "provenance": { "title": "Provenance", @@ -15053,16 +14521,10 @@ } }, "required": [ - "content" + "asset_type" ], - "additionalProperties": true - }, - { - "title": "DAAST Asset", - "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", "oneOf": [ { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -15073,358 +14535,14 @@ "type": "string", "format": "uri", "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -15434,363 +14552,29 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "title": "DAAST Version", - "description": "DAAST specification version", - "type": "string", - "enum": [ - "1.0", - "1.1" - ] - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "title": "DAAST Tracking Event", - "description": "Tracking events for audio ads. Includes DAAST-applicable events from IAB VAST/DAAST conventions, plus flattened Impression, Error, and ViewableImpression elements. creativeView included for companion ad tracking. measurableImpression is an AdCP extension.", - "type": "string", - "enum": [ - "impression", - "creativeView", - "loaded", - "start", - "firstQuartile", - "midpoint", - "thirdQuartile", - "complete", - "mute", - "unmute", - "pause", - "resume", - "skip", - "progress", - "clickTracking", - "customClick", - "close", - "error", - "viewable", - "notViewable", - "viewUndetermined", - "measurableImpression", - "viewableImpression" - ] - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "title": "Provenance", - "description": "Provenance metadata for this asset, overrides manifest-level provenance", - "type": "object", - "properties": { - "digital_source_type": { - "title": "Digital Source Type", - "description": "IPTC-aligned classification of AI involvement in producing this content", - "type": "string", - "enum": [ - "digital_capture", - "digital_creation", - "trained_algorithmic_media", - "composite_with_trained_algorithmic_media", - "algorithmic_media", - "composite_capture", - "composite_synthetic", - "human_edits", - "data_driven_media" - ], - "enumDescriptions": { - "digital_capture": "Captured by a digital device (camera, scanner, screen recording) with no AI involvement", - "digital_creation": "Created by a human using digital tools (Photoshop, Illustrator, After Effects) without AI generation", - "trained_algorithmic_media": "Generated entirely by a trained AI model (DALL-E, Midjourney, Stable Diffusion, Sora)", - "composite_with_trained_algorithmic_media": "Human-created content combined with AI-generated elements (e.g., photo with AI background)", - "algorithmic_media": "Produced by deterministic algorithms without machine learning (procedural generation, rule-based systems)", - "composite_capture": "Multiple digital captures composited together without AI", - "composite_synthetic": "Composite of multiple elements where at least one is AI-generated (e.g., stock photo composited with AI-generated background)", - "human_edits": "Content augmented, corrected, or enhanced by humans using non-generative tools", - "data_driven_media": "Assembled from structured data feeds (DCO templates, product catalogs, weather-triggered variants)" - } - }, - "ai_tool": { - "type": "object", - "description": "AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.", - "properties": { - "name": { - "type": "string", - "description": "Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')" - }, - "version": { - "type": "string", - "description": "Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version." - }, - "provider": { - "type": "string", - "description": "Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')" - } - }, - "required": [ - "name" - ], - "additionalProperties": true - }, - "human_oversight": { - "type": "string", - "description": "Level of human involvement in the AI-assisted creation process", - "enum": [ - "none", - "prompt_only", - "selected", - "edited", - "directed" - ], - "enumDescriptions": { - "none": "Fully automated with no human involvement in generation", - "prompt_only": "Human provided the prompt or instructions but did not review outputs", - "selected": "Human selected from multiple AI-generated candidates", - "edited": "Human edited or refined AI-generated output", - "directed": "Human directed the creative process with AI as an assistive tool" - } - }, - "declared_by": { - "type": "object", - "description": "Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.", - "properties": { - "agent_url": { - "type": "string", - "format": "uri", - "description": "URL of the agent or service that declared this provenance" - }, - "role": { - "type": "string", - "enum": [ - "creator", - "advertiser", - "agency", - "platform", - "tool" - ], - "description": "Role of the declaring party in the supply chain", - "enumDescriptions": { - "creator": "The party that created or generated the content", - "advertiser": "The brand or advertiser that owns the content", - "agency": "Agency acting on behalf of the advertiser", - "platform": "Ad platform or publisher that processed the content", - "tool": "Automated tool or service that attached provenance metadata" - } - } - }, - "required": [ - "role" - ], - "additionalProperties": true - }, - "declared_at": { - "type": "string", - "format": "date-time", - "description": "When this provenance claim was made (ISO 8601). Distinct from created_time, which records when the content itself was produced. A provenance claim may be attached well after content creation, for example when retroactively declaring AI involvement for regulatory compliance." - }, - "created_time": { - "type": "string", - "format": "date-time", - "description": "When this content was created or generated (ISO 8601)" - }, - "c2pa": { - "type": "object", - "description": "C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.", - "properties": { - "manifest_url": { - "type": "string", - "format": "uri", - "description": "URL to the C2PA manifest store for this content" - } - }, - "required": [ - "manifest_url" - ], - "additionalProperties": true - }, - "disclosure": { - "type": "object", - "description": "Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.", - "properties": { - "required": { - "type": "boolean", - "description": "Whether AI disclosure is required for this content based on applicable regulations" - }, - "jurisdictions": { - "type": "array", - "description": "Jurisdictions where disclosure obligations apply", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')" - }, - "region": { - "type": "string", - "description": "Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)" - }, - "regulation": { - "type": "string", - "description": "Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')" - }, - "label_text": { - "type": "string", - "description": "Required disclosure label text for this jurisdiction, in the local language" - }, - "render_guidance": { - "type": "object", - "description": "How the disclosure should be rendered for this jurisdiction. Expresses the declaring party's intent for persistence and position based on regulatory requirements. Publishers control actual rendering but governance agents can audit whether guidance was followed.", - "minProperties": 1, - "properties": { - "persistence": { - "title": "Disclosure Persistence", - "description": "How long the disclosure must persist during content playback or display", - "type": "string", - "enum": [ - "continuous", - "initial", - "flexible" - ], - "enumDescriptions": { - "continuous": "Disclosure must remain visible or audible throughout the entire content display duration. For video and audio, this means the full playback duration. For static formats (display, DOOH), this means the full display slot. For DOOH specifically, 'content duration' means the ad's display slot within the rotation, not the screen's full rotation cycle.", - "initial": "Disclosure must appear at the start of content for a minimum duration before it may be removed. Pair with min_duration_ms in render_guidance or creative brief to specify the required duration.", - "flexible": "Disclosure presence is sufficient; placement timing and duration are at the publisher's discretion" - } - }, - "min_duration_ms": { - "type": "integer", - "minimum": 1, - "description": "Minimum display duration in milliseconds for initial persistence. Recommended when persistence is initial \u2014 without it, the duration is at the publisher's discretion. At serve time the publisher reads this from provenance since the brief is not available." - }, - "positions": { - "type": "array", - "description": "Preferred disclosure positions in priority order. The first position a format supports should be used.", - "items": { - "title": "Disclosure Position", - "description": "Where a required disclosure should appear within a creative. Used by creative briefs to specify disclosure placement and by formats to declare which positions they can render.", - "type": "string", - "enum": [ - "prominent", - "footer", - "audio", - "subtitle", - "overlay", - "end_card", - "pre_roll", - "companion" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true - } - }, - "required": [ - "country", - "regulation" - ], - "additionalProperties": true - }, - "minItems": 1 - } - }, - "required": [ - "required" - ], - "additionalProperties": true - }, - "verification": { - "type": "array", - "description": "Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim \u2014 verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "verified_by": { - "type": "string", - "description": "Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')" - }, - "verified_time": { - "type": "string", - "format": "date-time", - "description": "When the verification was performed (ISO 8601)" - }, - "result": { - "type": "string", - "enum": [ - "authentic", - "ai_generated", - "ai_modified", - "inconclusive" - ], - "description": "Verification outcome" - }, - "confidence": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Confidence score of the verification result (0.0 to 1.0)" - }, - "details_url": { - "type": "string", - "format": "uri", - "description": "URL to the full verification report" - } - }, - "required": [ - "verified_by", - "result" - ], - "additionalProperties": true - } - }, - "ext": { - "title": "Extension Object", - "description": "Extension object for platform-specific, vendor-namespaced parameters. Extensions are always optional and must be namespaced under a vendor/platform key (e.g., ext.gam, ext.roku). Used for custom capabilities, partner-specific configuration, and features being proposed for standardization.", - "type": "object", - "additionalProperties": true - } - }, - "additionalProperties": true } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true }, { "title": "Markdown Asset", "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -15816,6 +14600,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true @@ -15823,6 +14608,17 @@ { "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Creative Brief", @@ -16016,6 +14812,17 @@ { "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "title": "Catalog", @@ -16489,7 +15296,10 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -17102,7 +15912,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.608Z", + "generatedAt": "2026-04-22T04:00:56.881Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/media-buy/update-media-buy-response.json b/schemas/cache/bundled/media-buy/update-media-buy-response.json index 90bcd8bd..f13646df 100644 --- a/schemas/cache/bundled/media-buy/update-media-buy-response.json +++ b/schemas/cache/bundled/media-buy/update-media-buy-response.json @@ -2879,7 +2879,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.620Z", + "generatedAt": "2026-04-22T04:00:56.891Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/create-property-list-request.json b/schemas/cache/bundled/property/create-property-list-request.json index fae26c15..69f5a922 100644 --- a/schemas/cache/bundled/property/create-property-list-request.json +++ b/schemas/cache/bundled/property/create-property-list-request.json @@ -705,7 +705,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.623Z", + "generatedAt": "2026-04-22T04:00:56.893Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/create-property-list-response.json b/schemas/cache/bundled/property/create-property-list-response.json index 961790ca..93cc194d 100644 --- a/schemas/cache/bundled/property/create-property-list-response.json +++ b/schemas/cache/bundled/property/create-property-list-response.json @@ -967,7 +967,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.624Z", + "generatedAt": "2026-04-22T04:00:56.894Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/delete-property-list-request.json b/schemas/cache/bundled/property/delete-property-list-request.json index f3d07b83..d0a6eae7 100644 --- a/schemas/cache/bundled/property/delete-property-list-request.json +++ b/schemas/cache/bundled/property/delete-property-list-request.json @@ -191,7 +191,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.625Z", + "generatedAt": "2026-04-22T04:00:56.895Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/delete-property-list-response.json b/schemas/cache/bundled/property/delete-property-list-response.json index ef767e75..3515df22 100644 --- a/schemas/cache/bundled/property/delete-property-list-response.json +++ b/schemas/cache/bundled/property/delete-property-list-response.json @@ -32,7 +32,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.625Z", + "generatedAt": "2026-04-22T04:00:56.895Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/get-property-list-request.json b/schemas/cache/bundled/property/get-property-list-request.json index c594c101..9cb0f3d2 100644 --- a/schemas/cache/bundled/property/get-property-list-request.json +++ b/schemas/cache/bundled/property/get-property-list-request.json @@ -205,7 +205,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.626Z", + "generatedAt": "2026-04-22T04:00:56.896Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/get-property-list-response.json b/schemas/cache/bundled/property/get-property-list-response.json index 9f889778..d4d382e3 100644 --- a/schemas/cache/bundled/property/get-property-list-response.json +++ b/schemas/cache/bundled/property/get-property-list-response.json @@ -1157,7 +1157,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.627Z", + "generatedAt": "2026-04-22T04:00:56.897Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/list-property-lists-request.json b/schemas/cache/bundled/property/list-property-lists-request.json index 8aefe652..08ba4fb5 100644 --- a/schemas/cache/bundled/property/list-property-lists-request.json +++ b/schemas/cache/bundled/property/list-property-lists-request.json @@ -197,7 +197,7 @@ }, "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.628Z", + "generatedAt": "2026-04-22T04:00:56.897Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/list-property-lists-response.json b/schemas/cache/bundled/property/list-property-lists-response.json index 16849d09..f98d9c3a 100644 --- a/schemas/cache/bundled/property/list-property-lists-response.json +++ b/schemas/cache/bundled/property/list-property-lists-response.json @@ -990,7 +990,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.629Z", + "generatedAt": "2026-04-22T04:00:56.899Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/update-property-list-request.json b/schemas/cache/bundled/property/update-property-list-request.json index ea55a27d..8d1a41d2 100644 --- a/schemas/cache/bundled/property/update-property-list-request.json +++ b/schemas/cache/bundled/property/update-property-list-request.json @@ -714,7 +714,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.630Z", + "generatedAt": "2026-04-22T04:00:56.900Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/update-property-list-response.json b/schemas/cache/bundled/property/update-property-list-response.json index cb1aaf9c..1821d663 100644 --- a/schemas/cache/bundled/property/update-property-list-response.json +++ b/schemas/cache/bundled/property/update-property-list-response.json @@ -962,7 +962,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.631Z", + "generatedAt": "2026-04-22T04:00:56.902Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/validate-property-delivery-request.json b/schemas/cache/bundled/property/validate-property-delivery-request.json index b03e2ba2..5ca67ef3 100644 --- a/schemas/cache/bundled/property/validate-property-delivery-request.json +++ b/schemas/cache/bundled/property/validate-property-delivery-request.json @@ -301,7 +301,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.632Z", + "generatedAt": "2026-04-22T04:00:56.903Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/property/validate-property-delivery-response.json b/schemas/cache/bundled/property/validate-property-delivery-response.json index 5a723cda..86271d17 100644 --- a/schemas/cache/bundled/property/validate-property-delivery-response.json +++ b/schemas/cache/bundled/property/validate-property-delivery-response.json @@ -403,7 +403,7 @@ ], "additionalProperties": false, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.633Z", + "generatedAt": "2026-04-22T04:00:56.903Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/protocol/get-adcp-capabilities-request.json b/schemas/cache/bundled/protocol/get-adcp-capabilities-request.json index ffa41985..0f7e2860 100644 --- a/schemas/cache/bundled/protocol/get-adcp-capabilities-request.json +++ b/schemas/cache/bundled/protocol/get-adcp-capabilities-request.json @@ -40,7 +40,7 @@ }, "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.633Z", + "generatedAt": "2026-04-22T04:00:56.904Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/protocol/get-adcp-capabilities-response.json b/schemas/cache/bundled/protocol/get-adcp-capabilities-response.json index 34531af4..b4f1ef58 100644 --- a/schemas/cache/bundled/protocol/get-adcp-capabilities-response.json +++ b/schemas/cache/bundled/protocol/get-adcp-capabilities-response.json @@ -1837,7 +1837,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.635Z", + "generatedAt": "2026-04-22T04:00:56.906Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/signals/activate-signal-request.json b/schemas/cache/bundled/signals/activate-signal-request.json index 87493709..474c7a70 100644 --- a/schemas/cache/bundled/signals/activate-signal-request.json +++ b/schemas/cache/bundled/signals/activate-signal-request.json @@ -262,7 +262,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.636Z", + "generatedAt": "2026-04-22T04:00:56.907Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/signals/activate-signal-response.json b/schemas/cache/bundled/signals/activate-signal-response.json index 24c2a3b5..59fca256 100644 --- a/schemas/cache/bundled/signals/activate-signal-response.json +++ b/schemas/cache/bundled/signals/activate-signal-response.json @@ -313,7 +313,7 @@ } ], "_bundled": { - "generatedAt": "2026-04-21T21:56:38.637Z", + "generatedAt": "2026-04-22T04:00:56.907Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/signals/get-signals-request.json b/schemas/cache/bundled/signals/get-signals-request.json index 0c0be6f4..0d4b8da2 100644 --- a/schemas/cache/bundled/signals/get-signals-request.json +++ b/schemas/cache/bundled/signals/get-signals-request.json @@ -401,7 +401,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.638Z", + "generatedAt": "2026-04-22T04:00:56.908Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/signals/get-signals-response.json b/schemas/cache/bundled/signals/get-signals-response.json index 0a6a3294..aad21339 100644 --- a/schemas/cache/bundled/signals/get-signals-response.json +++ b/schemas/cache/bundled/signals/get-signals-response.json @@ -682,7 +682,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.639Z", + "generatedAt": "2026-04-22T04:00:56.909Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-get-offering-request.json b/schemas/cache/bundled/sponsored-intelligence/si-get-offering-request.json index 8a5af147..dc87c49f 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-get-offering-request.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-get-offering-request.json @@ -16,9 +16,15 @@ "description": "Offering identifier from the catalog to get details for", "x-entity": "offering" }, - "context": { + "intent": { "type": "string", - "description": "Optional natural language context about user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." + "description": "Optional natural language description of user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." + }, + "context": { + "title": "Context Object", + "description": "Opaque correlation data that is echoed unchanged in responses. Used for internal tracking, UI session IDs, trace IDs, and other caller-specific identifiers that don't affect protocol behavior. Context data is never parsed by AdCP agents - it's simply preserved and returned.", + "type": "object", + "additionalProperties": true }, "include_products": { "type": "boolean", @@ -44,7 +50,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.639Z", + "generatedAt": "2026-04-22T04:00:56.909Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-get-offering-response.json b/schemas/cache/bundled/sponsored-intelligence/si-get-offering-response.json index a11f7e64..06f0e4fa 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-get-offering-response.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-get-offering-response.json @@ -200,7 +200,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.639Z", + "generatedAt": "2026-04-22T04:00:56.910Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-request.json b/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-request.json index 9dc170f8..8d3ffbec 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-request.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-request.json @@ -12,9 +12,15 @@ "minimum": 1, "maximum": 99 }, - "context": { + "intent": { "type": "string", - "description": "Conversation handoff from the host describing what the user needs" + "description": "Natural language description of user intent \u2014 the conversation handoff from the host describing what the user needs from the brand agent" + }, + "context": { + "title": "Context Object", + "description": "Opaque correlation data that is echoed unchanged in responses. Used for internal tracking, UI session IDs, trace IDs, and other caller-specific identifiers that don't affect protocol behavior. Context data is never parsed by AdCP agents - it's simply preserved and returned.", + "type": "object", + "additionalProperties": true }, "identity": { "title": "SI Identity", @@ -304,12 +310,12 @@ }, "required": [ "idempotency_key", - "context", + "intent", "identity" ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.640Z", + "generatedAt": "2026-04-22T04:00:56.910Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-response.json b/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-response.json index 4a515b0d..5066248f 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-response.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-initiate-session-response.json @@ -611,7 +611,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.641Z", + "generatedAt": "2026-04-22T04:00:56.911Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-send-message-request.json b/schemas/cache/bundled/sponsored-intelligence/si-send-message-request.json index 3c2dc3d5..aa218539 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-send-message-request.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-send-message-request.json @@ -74,7 +74,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.641Z", + "generatedAt": "2026-04-22T04:00:56.911Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-send-message-response.json b/schemas/cache/bundled/sponsored-intelligence/si-send-message-response.json index bde1b702..b427d2aa 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-send-message-response.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-send-message-response.json @@ -582,7 +582,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.642Z", + "generatedAt": "2026-04-22T04:00:56.912Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-request.json b/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-request.json index 963e3a95..167d9250 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-request.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-request.json @@ -80,7 +80,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.642Z", + "generatedAt": "2026-04-22T04:00:56.912Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-response.json b/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-response.json index e3e8c3ee..48f27cef 100644 --- a/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-response.json +++ b/schemas/cache/bundled/sponsored-intelligence/si-terminate-session-response.json @@ -149,7 +149,7 @@ ], "additionalProperties": true, "_bundled": { - "generatedAt": "2026-04-21T21:56:38.642Z", + "generatedAt": "2026-04-22T04:00:56.912Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } } \ No newline at end of file diff --git a/schemas/cache/core/assets/audio-asset.json b/schemas/cache/core/assets/audio-asset.json index 12817c48..a021db1a 100644 --- a/schemas/cache/core/assets/audio-asset.json +++ b/schemas/cache/core/assets/audio-asset.json @@ -4,6 +4,11 @@ "description": "Audio asset with URL and technical specifications", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "audio", + "description": "Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -75,6 +80,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true diff --git a/schemas/cache/core/assets/brief-asset.json b/schemas/cache/core/assets/brief-asset.json index 8b759145..a036f57e 100644 --- a/schemas/cache/core/assets/brief-asset.json +++ b/schemas/cache/core/assets/brief-asset.json @@ -2,6 +2,17 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Brief Asset", "description": "Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "brief", + "description": "Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "$ref": "../../core/creative-brief.json" diff --git a/schemas/cache/core/assets/catalog-asset.json b/schemas/cache/core/assets/catalog-asset.json index 68e6026f..03b8e8d4 100644 --- a/schemas/cache/core/assets/catalog-asset.json +++ b/schemas/cache/core/assets/catalog-asset.json @@ -2,6 +2,17 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Catalog Asset", "description": "A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "catalog", + "description": "Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + } + }, + "required": [ + "asset_type" + ], "allOf": [ { "$ref": "../../core/catalog.json" diff --git a/schemas/cache/core/assets/css-asset.json b/schemas/cache/core/assets/css-asset.json index 44e99ee8..261ef01d 100644 --- a/schemas/cache/core/assets/css-asset.json +++ b/schemas/cache/core/assets/css-asset.json @@ -4,6 +4,11 @@ "description": "CSS stylesheet asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "css", + "description": "Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "CSS content" @@ -18,6 +23,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true diff --git a/schemas/cache/core/assets/daast-asset.json b/schemas/cache/core/assets/daast-asset.json index 287d33de..a6afb2e7 100644 --- a/schemas/cache/core/assets/daast-asset.json +++ b/schemas/cache/core/assets/daast-asset.json @@ -2,9 +2,49 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "DAAST Asset", "description": "DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "daast", + "description": "Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + }, + "daast_version": { + "$ref": "../../enums/daast-version.json", + "description": "DAAST specification version" + }, + "duration_ms": { + "type": "integer", + "description": "Expected audio duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "$ref": "../../enums/daast-tracking-event.json" + }, + "description": "Tracking events supported by this DAAST tag" + }, + "companion_ads": { + "type": "boolean", + "description": "Whether companion display ads are included" + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the audio content", + "x-accessibility": true + }, + "provenance": { + "$ref": "../../core/provenance.json", + "description": "Provenance metadata for this asset, overrides manifest-level provenance" + } + }, + "required": [ + "asset_type" + ], "oneOf": [ { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -15,46 +55,14 @@ "type": "string", "format": "uri", "description": "URL endpoint that returns DAAST XML" - }, - "daast_version": { - "$ref": "../../enums/daast-version.json", - "description": "DAAST specification version" - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "$ref": "../../enums/daast-tracking-event.json" - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "$ref": "../../core/provenance.json", - "description": "Provenance metadata for this asset, overrides manifest-level provenance" } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -64,43 +72,16 @@ "content": { "type": "string", "description": "Inline DAAST XML content" - }, - "daast_version": { - "$ref": "../../enums/daast-version.json", - "description": "DAAST specification version" - }, - "duration_ms": { - "type": "integer", - "description": "Expected audio duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "$ref": "../../enums/daast-tracking-event.json" - }, - "description": "Tracking events supported by this DAAST tag" - }, - "companion_ads": { - "type": "boolean", - "description": "Whether companion display ads are included" - }, - "transcript_url": { - "type": "string", - "format": "uri", - "description": "URL to text transcript of the audio content", - "x-accessibility": true - }, - "provenance": { - "$ref": "../../core/provenance.json", - "description": "Provenance metadata for this asset, overrides manifest-level provenance" } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/core/assets/html-asset.json b/schemas/cache/core/assets/html-asset.json index 10d9a28d..db789e14 100644 --- a/schemas/cache/core/assets/html-asset.json +++ b/schemas/cache/core/assets/html-asset.json @@ -4,6 +4,11 @@ "description": "HTML content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "html", + "description": "Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "HTML content" @@ -41,6 +46,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true diff --git a/schemas/cache/core/assets/image-asset.json b/schemas/cache/core/assets/image-asset.json index 93bc2c58..d545c140 100644 --- a/schemas/cache/core/assets/image-asset.json +++ b/schemas/cache/core/assets/image-asset.json @@ -4,6 +4,11 @@ "description": "Image asset with URL and dimensions", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "image", + "description": "Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -34,6 +39,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" diff --git a/schemas/cache/core/assets/javascript-asset.json b/schemas/cache/core/assets/javascript-asset.json index 4c7ba560..533992c2 100644 --- a/schemas/cache/core/assets/javascript-asset.json +++ b/schemas/cache/core/assets/javascript-asset.json @@ -4,6 +4,11 @@ "description": "JavaScript code asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "javascript", + "description": "Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "JavaScript content" @@ -41,6 +46,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true diff --git a/schemas/cache/core/assets/markdown-asset.json b/schemas/cache/core/assets/markdown-asset.json index 7a650566..7eb04046 100644 --- a/schemas/cache/core/assets/markdown-asset.json +++ b/schemas/cache/core/assets/markdown-asset.json @@ -4,6 +4,11 @@ "description": "Markdown-formatted text content following CommonMark specification", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "markdown", + "description": "Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions" @@ -24,6 +29,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true diff --git a/schemas/cache/core/assets/text-asset.json b/schemas/cache/core/assets/text-asset.json index 75a20bb8..a03de725 100644 --- a/schemas/cache/core/assets/text-asset.json +++ b/schemas/cache/core/assets/text-asset.json @@ -4,6 +4,11 @@ "description": "Text content asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "text", + "description": "Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + }, "content": { "type": "string", "description": "Text content" @@ -18,6 +23,7 @@ } }, "required": [ + "asset_type", "content" ], "additionalProperties": true diff --git a/schemas/cache/core/assets/url-asset.json b/schemas/cache/core/assets/url-asset.json index da65a770..245d3b85 100644 --- a/schemas/cache/core/assets/url-asset.json +++ b/schemas/cache/core/assets/url-asset.json @@ -4,10 +4,15 @@ "description": "URL reference asset", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "url", + "description": "Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", - "format": "uri", - "description": "URL reference" + "format": "uri-template", + "description": "URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." }, "url_type": { "$ref": "../../enums/url-asset-type.json", @@ -23,6 +28,7 @@ } }, "required": [ + "asset_type", "url" ], "additionalProperties": true diff --git a/schemas/cache/core/assets/vast-asset.json b/schemas/cache/core/assets/vast-asset.json index 0cfc8596..940864a1 100644 --- a/schemas/cache/core/assets/vast-asset.json +++ b/schemas/cache/core/assets/vast-asset.json @@ -2,9 +2,55 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "VAST Asset", "description": "VAST (Video Ad Serving Template) tag for third-party video ad serving", + "type": "object", + "properties": { + "asset_type": { + "type": "string", + "const": "vast", + "description": "Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + }, + "vast_version": { + "$ref": "../../enums/vast-version.json", + "description": "VAST specification version" + }, + "vpaid_enabled": { + "type": "boolean", + "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" + }, + "duration_ms": { + "type": "integer", + "description": "Expected video duration in milliseconds (if known)", + "minimum": 0 + }, + "tracking_events": { + "type": "array", + "items": { + "$ref": "../../enums/vast-tracking-event.json" + }, + "description": "Tracking events supported by this VAST tag" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "audio_description_url": { + "type": "string", + "format": "uri", + "description": "URL to audio description track for visually impaired users", + "x-accessibility": true + }, + "provenance": { + "$ref": "../../core/provenance.json", + "description": "Provenance metadata for this asset, overrides manifest-level provenance" + } + }, + "required": [ + "asset_type" + ], "oneOf": [ { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -15,52 +61,14 @@ "type": "string", "format": "uri", "description": "URL endpoint that returns VAST XML" - }, - "vast_version": { - "$ref": "../../enums/vast-version.json", - "description": "VAST specification version" - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "$ref": "../../enums/vast-tracking-event.json" - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "$ref": "../../core/provenance.json", - "description": "Provenance metadata for this asset, overrides manifest-level provenance" } }, "required": [ "delivery_type", "url" - ], - "additionalProperties": true + ] }, { - "type": "object", "properties": { "delivery_type": { "type": "string", @@ -70,49 +78,16 @@ "content": { "type": "string", "description": "Inline VAST XML content" - }, - "vast_version": { - "$ref": "../../enums/vast-version.json", - "description": "VAST specification version" - }, - "vpaid_enabled": { - "type": "boolean", - "description": "Whether VPAID (Video Player-Ad Interface Definition) is supported" - }, - "duration_ms": { - "type": "integer", - "description": "Expected video duration in milliseconds (if known)", - "minimum": 0 - }, - "tracking_events": { - "type": "array", - "items": { - "$ref": "../../enums/vast-tracking-event.json" - }, - "description": "Tracking events supported by this VAST tag" - }, - "captions_url": { - "type": "string", - "format": "uri", - "description": "URL to captions file (WebVTT, SRT, etc.)", - "x-accessibility": true - }, - "audio_description_url": { - "type": "string", - "format": "uri", - "description": "URL to audio description track for visually impaired users", - "x-accessibility": true - }, - "provenance": { - "$ref": "../../core/provenance.json", - "description": "Provenance metadata for this asset, overrides manifest-level provenance" } }, "required": [ "delivery_type", "content" - ], - "additionalProperties": true + ] } - ] + ], + "discriminator": { + "propertyName": "delivery_type" + }, + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/core/assets/video-asset.json b/schemas/cache/core/assets/video-asset.json index ce734c34..8a4c5dc6 100644 --- a/schemas/cache/core/assets/video-asset.json +++ b/schemas/cache/core/assets/video-asset.json @@ -4,6 +4,11 @@ "description": "Video asset with URL and technical specifications including audio track properties", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "video", + "description": "Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -190,6 +195,7 @@ } }, "required": [ + "asset_type", "url", "width", "height" diff --git a/schemas/cache/core/assets/webhook-asset.json b/schemas/cache/core/assets/webhook-asset.json index 0902e052..64eda2b5 100644 --- a/schemas/cache/core/assets/webhook-asset.json +++ b/schemas/cache/core/assets/webhook-asset.json @@ -4,6 +4,11 @@ "description": "Webhook for server-side dynamic content rendering (DCO)", "type": "object", "properties": { + "asset_type": { + "type": "string", + "const": "webhook", + "description": "Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + }, "url": { "type": "string", "format": "uri", @@ -24,7 +29,7 @@ "supported_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "$ref": "../../enums/universal-macro.json" }, @@ -39,7 +44,7 @@ "required_macros": { "type": "array", "items": { - "oneOf": [ + "anyOf": [ { "$ref": "../../enums/universal-macro.json" }, @@ -82,6 +87,7 @@ } }, "required": [ + "asset_type", "url", "response_type", "security" diff --git a/schemas/cache/core/creative-asset.json b/schemas/cache/core/creative-asset.json index 983b2562..bcb4d634 100644 --- a/schemas/cache/core/creative-asset.json +++ b/schemas/cache/core/creative-asset.json @@ -19,10 +19,10 @@ }, "assets": { "type": "object", - "description": "Assets required by the format, keyed by asset_id", + "description": "Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "$ref": "assets/image-asset.json" }, @@ -65,7 +65,10 @@ { "$ref": "assets/catalog-asset.json" } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true diff --git a/schemas/cache/core/creative-manifest.json b/schemas/cache/core/creative-manifest.json index d6ae8728..c51f3378 100644 --- a/schemas/cache/core/creative-manifest.json +++ b/schemas/cache/core/creative-manifest.json @@ -10,10 +10,10 @@ }, "assets": { "type": "object", - "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance \u2014 each asset must match at least one valid asset type schema.", + "description": "Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "$ref": "assets/image-asset.json" }, @@ -56,7 +56,10 @@ { "$ref": "assets/catalog-asset.json" } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true diff --git a/schemas/cache/core/offering-asset-group.json b/schemas/cache/core/offering-asset-group.json index 5c39e671..499ff325 100644 --- a/schemas/cache/core/offering-asset-group.json +++ b/schemas/cache/core/offering-asset-group.json @@ -14,9 +14,9 @@ }, "items": { "type": "array", - "description": "The assets in this group. Each item should match the structure for the declared asset_type. Note: JSON Schema validation accepts any valid asset structure here; enforcement that items match asset_type is the responsibility of the consuming agent.", + "description": "The assets in this group. Each item carries an `asset_type` discriminator that selects the matching asset schema. Note: the group-level `asset_type` declares the expected type; individual items must also self-tag so validators can narrow errors.", "items": { - "anyOf": [ + "oneOf": [ { "$ref": "assets/text-asset.json" }, @@ -53,7 +53,10 @@ { "$ref": "assets/webhook-asset.json" } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } }, "minItems": 1 }, @@ -75,12 +78,15 @@ "asset_type": "text", "items": [ { + "asset_type": "text", "content": "Shop the Summer Sale" }, { + "asset_type": "text", "content": "50% Off Everything" }, { + "asset_type": "text", "content": "Summer Savings Event" } ] @@ -93,11 +99,13 @@ "asset_type": "image", "items": [ { + "asset_type": "image", "url": "https://cdn.acme.com/hero.jpg", "width": 1200, "height": 628 }, { + "asset_type": "image", "url": "https://cdn.acme.com/hero2.jpg", "width": 1200, "height": 628 diff --git a/schemas/cache/core/offering.json b/schemas/cache/core/offering.json index a9b34053..8d703303 100644 --- a/schemas/cache/core/offering.json +++ b/schemas/cache/core/offering.json @@ -222,12 +222,15 @@ "asset_type": "text", "items": [ { + "asset_type": "text", "content": "Shop the Summer Sale" }, { + "asset_type": "text", "content": "50% Off Everything" }, { + "asset_type": "text", "content": "Summer Savings Event" } ] @@ -237,6 +240,7 @@ "asset_type": "image", "items": [ { + "asset_type": "image", "url": "https://cdn.acme.com/hero.jpg", "width": 1200, "height": 628 @@ -248,6 +252,7 @@ "asset_type": "image", "items": [ { + "asset_type": "image", "url": "https://cdn.acme.com/sq.jpg", "width": 600, "height": 600 diff --git a/schemas/cache/creative/asset-types/index.json b/schemas/cache/creative/asset-types/index.json index 2c859456..9b6f8249 100644 --- a/schemas/cache/creative/asset-types/index.json +++ b/schemas/cache/creative/asset-types/index.json @@ -3,7 +3,7 @@ "title": "AdCP Asset Type Registry", "description": "Registry of asset types used in AdCP creative manifests. Each asset type defines the structure of actual content payloads (what you send), not requirements or constraints (which belong in format specifications).", "version": "1.0.0", - "lastUpdated": "2026-04-21", + "lastUpdated": "2026-04-22", "asset_types": { "image": { "description": "Static image asset (JPG, PNG, GIF, WebP, SVG)", @@ -95,11 +95,18 @@ "3. For each asset in manifest, look up asset_id in format's assets array", "4. Validate asset matches the type and requirements defined in the format" ] + }, + "nested_discriminator_pattern": { + "description": "Asset schemas with internal variants (e.g., VAST and DAAST support both URL-delivery and inline XML) use a two-level discriminator rather than splitting each variant into a separate top-level asset_type. The outer discriminator (`asset_type` on the composite map) selects the asset schema; an inner `oneOf` + `discriminator` inside that schema selects the variant. Future asset types with internal variants should follow this pattern \u2014 do not introduce sibling entries like `vast_url` and `vast_inline` at the registry level.", + "examples": [ + "vast-asset.json: outer asset_type='vast', inner delivery_type='url'|'inline'", + "daast-asset.json: outer asset_type='daast', inner delivery_type='url'|'inline'" + ] } }, "usage_notes": { "format_specs": "Format specifications define what asset_ids are required (e.g., 'hero_image', 'logo'). Each defines its asset type and constraints (dimensions, file size, etc.).", - "creative_manifests": "Creative manifests provide actual asset content, keyed by asset_id from the format. Asset type is determined by the format specification, not declared in the payload.", + "creative_manifests": "Creative manifests provide actual asset content, keyed by asset_id from the format. Each asset value carries an `asset_type` discriminator (one of the registry keys) so validators can select the matching asset schema and report errors against only that branch. The format specification also defines what asset_type each asset_id should have \u2014 payload and format should agree.", "example_flow": "Format says 'hero_image' must be type 'image' with width 1200, height 627. Manifest provides hero_image: {url: '...', width: 1200, height: 627}. The format spec tells us it's an image type." }, "adcp_version": "latest", diff --git a/schemas/cache/creative/list-creatives-response.json b/schemas/cache/creative/list-creatives-response.json index 39b0c1ec..931c88e8 100644 --- a/schemas/cache/creative/list-creatives-response.json +++ b/schemas/cache/creative/list-creatives-response.json @@ -86,10 +86,10 @@ }, "assets": { "type": "object", - "description": "Assets for this creative, keyed by asset_id", + "description": "Assets for this creative, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema.", "patternProperties": { "^[a-z0-9_]+$": { - "anyOf": [ + "oneOf": [ { "$ref": "../core/assets/image-asset.json" }, @@ -132,7 +132,10 @@ { "$ref": "../core/assets/catalog-asset.json" } - ] + ], + "discriminator": { + "propertyName": "asset_type" + } } }, "additionalProperties": true @@ -365,11 +368,13 @@ "updated_date": "2026-02-20T09:30:00Z", "assets": { "banner_image": { + "asset_type": "image", "url": "https://cdn.example.com/holiday_300x250.png", "width": 300, "height": 250 }, "clickthrough_url": { + "asset_type": "url", "url": "https://acmecorp.example.com/holiday-sale" } }, @@ -409,11 +414,13 @@ "updated_date": "2026-02-20T09:35:00Z", "assets": { "banner_image": { + "asset_type": "image", "url": "https://cdn.example.com/holiday_728x90.png", "width": 728, "height": 90 }, "clickthrough_url": { + "asset_type": "url", "url": "https://acmecorp.example.com/holiday-sale" } }, diff --git a/schemas/cache/creative/sync-creatives-request.json b/schemas/cache/creative/sync-creatives-request.json index ca965c8c..32f49516 100644 --- a/schemas/cache/creative/sync-creatives-request.json +++ b/schemas/cache/creative/sync-creatives-request.json @@ -130,6 +130,7 @@ }, "assets": { "video": { + "asset_type": "video", "url": "https://cdn.example.com/hero-video.mp4", "width": 1920, "height": 1080, @@ -171,10 +172,12 @@ }, "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" } }, @@ -207,6 +210,7 @@ }, "assets": { "video": { + "asset_type": "video", "url": "https://cdn.example.com/updated-hero.mp4", "width": 1920, "height": 1080, @@ -223,6 +227,7 @@ }, "assets": { "image": { + "asset_type": "image", "url": "https://cdn.example.com/updated-banner.png", "width": 300, "height": 250 diff --git a/schemas/cache/extensions/index.json b/schemas/cache/extensions/index.json index c37fcbc4..f828d151 100644 --- a/schemas/cache/extensions/index.json +++ b/schemas/cache/extensions/index.json @@ -3,6 +3,6 @@ "title": "AdCP Extension Registry", "description": "Auto-generated registry of formal AdCP extensions. Extensions provide typed schemas for vendor-specific or domain-specific data within the ext field. Agents declare which extensions they support in their agent card.", "_generated": true, - "_generatedAt": "2026-04-21T21:56:38.321Z", + "_generatedAt": "2026-04-22T04:00:56.617Z", "extensions": {} } \ No newline at end of file diff --git a/schemas/cache/governance/check-governance-request.json b/schemas/cache/governance/check-governance-request.json index a80773cd..1d4fc5a6 100644 --- a/schemas/cache/governance/check-governance-request.json +++ b/schemas/cache/governance/check-governance-request.json @@ -13,7 +13,7 @@ }, "plan_id": { "type": "string", - "description": "Campaign governance plan identifier.", + "description": "Campaign governance plan identifier. The plan uniquely scopes the account and operator; do not include a separate `account` field \u2014 the governance agent resolves account from the plan. Including `account` is rejected by `additionalProperties: false`.", "x-entity": "governance_plan" }, "caller": { diff --git a/schemas/cache/governance/get-plan-audit-logs-request.json b/schemas/cache/governance/get-plan-audit-logs-request.json index 1c5fa379..2125760b 100644 --- a/schemas/cache/governance/get-plan-audit-logs-request.json +++ b/schemas/cache/governance/get-plan-audit-logs-request.json @@ -18,7 +18,7 @@ "x-entity": "governance_plan" }, "minItems": 1, - "description": "Plan IDs to retrieve. For a single plan, pass a one-element array." + "description": "Plan IDs to retrieve. For a single plan, pass a one-element array. Plans uniquely scope account and operator; do not include a separate `account` field \u2014 the governance agent resolves account from each plan. Including `account` is rejected by `additionalProperties: false`." }, "portfolio_plan_ids": { "type": "array", diff --git a/schemas/cache/governance/report-plan-outcome-request.json b/schemas/cache/governance/report-plan-outcome-request.json index 42e82f82..3ef2dd96 100644 --- a/schemas/cache/governance/report-plan-outcome-request.json +++ b/schemas/cache/governance/report-plan-outcome-request.json @@ -14,7 +14,7 @@ }, "plan_id": { "type": "string", - "description": "The plan this outcome is for.", + "description": "The plan this outcome is for. The plan uniquely scopes the account and operator; do not include a separate `account` field \u2014 the governance agent resolves account from the plan. Including `account` is rejected by `additionalProperties: false`.", "x-entity": "governance_plan" }, "check_id": { diff --git a/schemas/cache/index.json b/schemas/cache/index.json index a5eec5ff..1ff41369 100644 --- a/schemas/cache/index.json +++ b/schemas/cache/index.json @@ -7,7 +7,7 @@ "versioning": { "note": "AdCP uses build-time versioning. This directory contains schemas for AdCP latest. Full semantic versions are available at /schemas/{version}/ (e.g., /schemas/2.5.0/). Major version aliases point to the latest release: /schemas/vlatest/ \u2192 /schemas/latest/." }, - "lastUpdated": "2026-04-21", + "lastUpdated": "2026-04-22", "baseUrl": "/schemas/latest", "schemas": { "core": { diff --git a/schemas/cache/media-buy/get-products-request.json b/schemas/cache/media-buy/get-products-request.json index ed565309..deabb7ed 100644 --- a/schemas/cache/media-buy/get-products-request.json +++ b/schemas/cache/media-buy/get-products-request.json @@ -29,6 +29,9 @@ "minItems": 1, "items": { "type": "object", + "discriminator": { + "propertyName": "scope" + }, "oneOf": [ { "properties": { @@ -56,7 +59,7 @@ "const": "product", "description": "Change scoped to a specific product." }, - "id": { + "product_id": { "type": "string", "minLength": 1, "description": "Product ID from a previous get_products response." @@ -68,7 +71,8 @@ "omit", "more_like_this" ], - "description": "'include': return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned)." + "default": "include", + "description": "'include' (default): return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned). Optional \u2014 when omitted, the seller treats the entry as action: 'include'." }, "ask": { "type": "string", @@ -78,8 +82,7 @@ }, "required": [ "scope", - "id", - "action" + "product_id" ], "additionalProperties": false }, @@ -90,7 +93,7 @@ "const": "proposal", "description": "Change scoped to a specific proposal." }, - "id": { + "proposal_id": { "type": "string", "minLength": 1, "description": "Proposal ID from a previous get_products response." @@ -102,7 +105,8 @@ "omit", "finalize" ], - "description": "'include': return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold \u2014 transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests \u2014 they represent a commitment to wait for the result." + "default": "include", + "description": "'include' (default): return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold \u2014 transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests \u2014 they represent a commitment to wait for the result. Optional \u2014 when omitted, the seller treats the entry as action: 'include'." }, "ask": { "type": "string", @@ -112,8 +116,7 @@ }, "required": [ "scope", - "id", - "action" + "proposal_id" ], "additionalProperties": false } diff --git a/schemas/cache/media-buy/get-products-response.json b/schemas/cache/media-buy/get-products-response.json index 1f4e0c4e..1db07558 100644 --- a/schemas/cache/media-buy/get-products-response.json +++ b/schemas/cache/media-buy/get-products-response.json @@ -35,41 +35,105 @@ }, "refinement_applied": { "type": "array", - "description": "Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'.", + "description": "Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'. Each entry MUST echo the request entry's scope and \u2014 for product and proposal scopes \u2014 the matching id field (product_id or proposal_id), so orchestrators can cross-validate alignment.", "items": { "type": "object", - "properties": { - "scope": { - "type": "string", - "enum": [ - "request", - "product", - "proposal" + "discriminator": { + "propertyName": "scope" + }, + "oneOf": [ + { + "properties": { + "scope": { + "type": "string", + "const": "request", + "description": "Echoes scope 'request' from the corresponding refine entry." + }, + "status": { + "type": "string", + "enum": [ + "applied", + "partial", + "unable" + ], + "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + }, + "notes": { + "type": "string", + "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + } + }, + "required": [ + "scope", + "status" ], - "description": "Echoes the scope from the corresponding refine entry. Allows orchestrators to cross-validate alignment." - }, - "id": { - "type": "string", - "description": "Echoes the id from the corresponding refine entry (for product and proposal scopes)." + "additionalProperties": false }, - "status": { - "type": "string", - "enum": [ - "applied", - "partial", - "unable" + { + "properties": { + "scope": { + "type": "string", + "const": "product", + "description": "Echoes scope 'product' from the corresponding refine entry." + }, + "product_id": { + "type": "string", + "description": "Echoes product_id from the corresponding refine entry." + }, + "status": { + "type": "string", + "enum": [ + "applied", + "partial", + "unable" + ], + "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + }, + "notes": { + "type": "string", + "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + } + }, + "required": [ + "scope", + "product_id", + "status" ], - "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + "additionalProperties": false }, - "notes": { - "type": "string", - "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + { + "properties": { + "scope": { + "type": "string", + "const": "proposal", + "description": "Echoes scope 'proposal' from the corresponding refine entry." + }, + "proposal_id": { + "type": "string", + "description": "Echoes proposal_id from the corresponding refine entry." + }, + "status": { + "type": "string", + "enum": [ + "applied", + "partial", + "unable" + ], + "description": "'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled \u2014 see notes for details. 'unable': the seller could not fulfill the ask \u2014 see notes for why." + }, + "notes": { + "type": "string", + "description": "Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." + } + }, + "required": [ + "scope", + "proposal_id", + "status" + ], + "additionalProperties": false } - }, - "required": [ - "status" - ], - "additionalProperties": false + ] } }, "incomplete": { diff --git a/schemas/cache/sponsored-intelligence/si-get-offering-request.json b/schemas/cache/sponsored-intelligence/si-get-offering-request.json index 3324533b..2a879b8f 100644 --- a/schemas/cache/sponsored-intelligence/si-get-offering-request.json +++ b/schemas/cache/sponsored-intelligence/si-get-offering-request.json @@ -16,9 +16,12 @@ "description": "Offering identifier from the catalog to get details for", "x-entity": "offering" }, - "context": { + "intent": { "type": "string", - "description": "Optional natural language context about user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." + "description": "Optional natural language description of user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." + }, + "context": { + "$ref": "../core/context.json" }, "include_products": { "type": "boolean", diff --git a/schemas/cache/sponsored-intelligence/si-initiate-session-request.json b/schemas/cache/sponsored-intelligence/si-initiate-session-request.json index 655d2004..751dd6de 100644 --- a/schemas/cache/sponsored-intelligence/si-initiate-session-request.json +++ b/schemas/cache/sponsored-intelligence/si-initiate-session-request.json @@ -12,9 +12,12 @@ "minimum": 1, "maximum": 99 }, - "context": { + "intent": { "type": "string", - "description": "Conversation handoff from the host describing what the user needs" + "description": "Natural language description of user intent \u2014 the conversation handoff from the host describing what the user needs from the brand agent" + }, + "context": { + "$ref": "../core/context.json" }, "identity": { "$ref": "si-identity.json" @@ -54,7 +57,7 @@ }, "required": [ "idempotency_key", - "context", + "intent", "identity" ], "additionalProperties": true diff --git a/scripts/post_generate_fixes.py b/scripts/post_generate_fixes.py index 2d011e8d..134623d6 100644 --- a/scripts/post_generate_fixes.py +++ b/scripts/post_generate_fixes.py @@ -643,6 +643,162 @@ def restore_format_category_deprecation_shim(): print(f" ✓ Restored format_category deprecation shim at {rel}") +def inject_literal_discriminator_defaults() -> None: + """Inject defaults for ``Literal[]`` required fields. + + AdCP's schema marks discriminator fields like ``asset_type``, + ``delivery_type``, ``pricing_model`` as required even though the + field's type is ``Literal[]`` — the spec's intent is + "this field MUST be this one tag", not "the user MUST type the + tag out by hand". Pydantic takes the spec literally and generates + the field as required, breaking ergonomic construction:: + + # Spec-literal generated shape: + text = TextAsset(asset_type="text", content="hello") + + # With this fix: + text = TextAsset(content="hello") # asset_type defaults to "text" + + Wire consumption is unchanged — the ``Literal`` type still rejects + any value other than the tag, and validating a dict from the wire + still populates the field the same way. This only affects + in-process construction ergonomics. + + The fix is pattern-based: any ``AnnAssign`` whose annotation is + ``Literal['x']`` (or ``Annotated[Literal['x'], ...]``) and has no + default gets ``= 'x'`` appended. No spec-value-specific logic. + Robust to spec churn as long as the single-value-Literal pattern + holds. + """ + import ast + + total_classes = 0 + total_fields = 0 + total_files = 0 + + for py_file in sorted(OUTPUT_DIR.rglob("*.py")): + if py_file.name == "__init__.py": + continue + + source = py_file.read_text() + try: + tree = ast.parse(source) + except SyntaxError: + continue + + edits: list[tuple[int, str]] = [] # (end_lineno, literal_value) + + for node in ast.walk(tree): + if not isinstance(node, ast.ClassDef): + continue + class_has_edit = False + for stmt in node.body: + if not isinstance(stmt, ast.AnnAssign): + continue + if stmt.value is not None: + continue # already has a default + literal_value = _extract_single_literal_value(stmt.annotation) + if literal_value is None: + continue + # ast end_lineno is 1-indexed, inclusive. The annotation + # ends on that line; we want to append " = ''" at + # end of that line. + edits.append((stmt.end_lineno, literal_value)) + total_fields += 1 + class_has_edit = True + if class_has_edit: + total_classes += 1 + + if not edits: + continue + + # Apply line-based edits. Sort descending so earlier edits don't + # shift the line indices of later ones (we're editing in place + # without inserting new lines, but defensive). + lines = source.split("\n") + for end_lineno, value in sorted(edits, key=lambda e: -e[0]): + idx = end_lineno - 1 # 0-indexed + # Escape the literal value as a Python string literal. + # datamodel-codegen only emits str-valued Literals for + # discriminators in AdCP schemas; if the value isn't a str, + # skip conservatively. + if not isinstance(value, str): + continue + escaped = repr(value) + lines[idx] = f"{lines[idx]} = {escaped}" + + py_file.write_text("\n".join(lines)) + total_files += 1 + + print( + f" ✓ Injected Literal[] defaults: " + f"{total_fields} fields across {total_classes} classes in {total_files} files" + ) + + +def _extract_single_literal_value(annotation: ast.AST) -> object | None: + """Return the single Literal value if the annotation is effectively + ``Literal[X]`` (optionally wrapped in ``Annotated[...]``); else None. + + Handles both shapes datamodel-codegen emits: + + * ``Literal['text']`` — bare Literal + * ``Annotated[Literal['text'], Field(...)]`` — wrapped in Annotated + with a Field descriptor (the typical discriminator shape) + + Returns None if the annotation is a Literal with multiple values, + a Literal over non-strings, or anything else. We only want to + auto-default the unambiguous single-tag case. + """ + import ast + + # Unwrap Annotated[X, ...] → X + if isinstance(annotation, ast.Subscript) and _subscript_base_name(annotation) == "Annotated": + inner = _first_subscript_arg(annotation) + if inner is None: + return None + annotation = inner + + # Expect Literal[X] + if not isinstance(annotation, ast.Subscript): + return None + if _subscript_base_name(annotation) != "Literal": + return None + + # Extract the subscript arg(s). Single-value case only. + # ast.Subscript.slice in 3.9+ is the value directly (not a Tuple for single). + slice_node = annotation.slice + if isinstance(slice_node, ast.Tuple): + # Literal['a', 'b'] — multiple values, skip + return None + if not isinstance(slice_node, ast.Constant): + return None + return slice_node.value + + +def _subscript_base_name(node: ast.Subscript) -> str | None: + """Return the subscripted name (e.g. 'Literal' for Literal['x']).""" + import ast + + value = node.value + if isinstance(value, ast.Name): + return value.id + if isinstance(value, ast.Attribute): + return value.attr + return None + + +def _first_subscript_arg(node: ast.Subscript) -> ast.AST | None: + """Return the first argument of a subscript. For Annotated[X, ...] + this is X; for single-arg Literal[X] this is the constant node.""" + import ast + + slice_node = node.slice + if isinstance(slice_node, ast.Tuple): + return slice_node.elts[0] if slice_node.elts else None + return slice_node + + def main(): """Apply all post-generation fixes.""" print("Applying post-generation fixes...") @@ -659,6 +815,7 @@ def main(): fix_list_field_shadowing() fix_reuse_model_discriminator_bug() restore_format_category_deprecation_shim() + inject_literal_discriminator_defaults() print("\n✓ Post-generation fixes complete\n") diff --git a/src/adcp/types/_generated.py b/src/adcp/types/_generated.py index 42012d6b..803702b3 100644 --- a/src/adcp/types/_generated.py +++ b/src/adcp/types/_generated.py @@ -10,7 +10,7 @@ DO NOT EDIT MANUALLY. Generated from: https://github.com/adcontextprotocol/adcp/tree/main/schemas -Generation date: 2026-04-21 22:42:50 UTC +Generation date: 2026-04-22 04:28:13 UTC """ # ruff: noqa: E501, I001 @@ -654,7 +654,7 @@ from adcp.types.generated_poc.core.media_buy import Cancellation, MediaBuy from adcp.types.generated_poc.core.media_buy_features import MediaBuyFeatures from adcp.types.generated_poc.core.offering import GeoTargets, Metro, Offering, PostalArea, Region -from adcp.types.generated_poc.core.offering_asset_group import OfferingAssetGroup +from adcp.types.generated_poc.core.offering_asset_group import Items, OfferingAssetGroup from adcp.types.generated_poc.core.optimization_goal import ( EventSource, Metric, @@ -1049,7 +1049,7 @@ ) from adcp.types.generated_poc.governance.sync_plans_response import ( ResolvedPolicy, - Status38, + Status42, SyncPlansResponse, ) from adcp.types.generated_poc.media_buy.build_creative_async_response_input_required import ( @@ -1142,12 +1142,15 @@ Refine, Refine1, Refine2, + Refine3, ) from adcp.types.generated_poc.media_buy.get_products_response import ( GetProductsResponse, IncompleteItem, - RefinementAppliedItem, - Scope3, + RefinementApplied, + RefinementApplied1, + RefinementApplied2, + RefinementApplied3, ) from adcp.types.generated_poc.media_buy.list_creative_formats_request import ( ListCreativeFormatsRequest, @@ -1299,7 +1302,7 @@ ) from adcp.types.generated_poc.property.validation_result import ( Requirement, - Status52, + Status56, ValidationResult, ) from adcp.types.generated_poc.protocol.get_adcp_capabilities_request import ( @@ -2241,7 +2244,6 @@ Disclosure135, Disclosure136, Disclosure137, - Items, Items1, Jurisdiction132, Jurisdiction133, @@ -2294,7 +2296,7 @@ RenderGuidance136, Role153, Role166, - Status22, + Status26, TrackingEvent26, Variable, VerificationItem125, @@ -2750,7 +2752,7 @@ DataSubjectContestation89, Error35, Error36, - Status34, + Status38, SyncCreativesResponse4, SyncCreativesResponse5, SyncCreativesResponse6, @@ -3391,7 +3393,8 @@ Radius11, Radius12, Refine4, - Refine5, + Refine6, + Refine7, RequiredFeatures, RequiredPerformanceStandard, SignalId9, @@ -3551,6 +3554,9 @@ Reach3, Reach4, Reach5, + RefinementApplied4, + RefinementApplied6, + RefinementApplied7, RequiredEventType, Saves, Saves1, @@ -3558,14 +3564,13 @@ Saves3, Saves4, Saves5, - Scope5, Spend2, Spend3, Spend4, Spend5, Spend6, - Status17, - Status18, + Status19, + Status20, SupportedTarget1, SupportsGeoBreakdown, Type46, @@ -4310,8 +4315,8 @@ ) from adcp.types.generated_poc.bundled.property.validate_property_delivery_response import ( Authorization, - Status49, - Status50, + Status53, + Status54, ) from adcp.types.generated_poc.bundled.protocol.get_adcp_capabilities_response import ( AvailableUs, @@ -7246,9 +7251,17 @@ "Refine", "Refine1", "Refine2", + "Refine3", "Refine4", - "Refine5", - "RefinementAppliedItem", + "Refine6", + "Refine7", + "RefinementApplied", + "RefinementApplied1", + "RefinementApplied2", + "RefinementApplied3", + "RefinementApplied4", + "RefinementApplied6", + "RefinementApplied7", "Region", "RegulatoryBasi", "RegulatoryFramework", @@ -7643,8 +7656,6 @@ "Scenario", "Scheme", "Scope", - "Scope3", - "Scope5", "Secondary", "Secondary1", "Secondary1Item", @@ -7724,14 +7735,14 @@ "Status", "Status11", "Status13", - "Status17", - "Status18", - "Status22", - "Status34", + "Status19", + "Status20", + "Status26", "Status38", - "Status49", - "Status50", - "Status52", + "Status42", + "Status53", + "Status54", + "Status56", "Status6", "StatusFilter", "StatusFilter2", diff --git a/src/adcp/types/generated_poc/a2ui/bound_value.py b/src/adcp/types/generated_poc/a2ui/bound_value.py index aee9f460..f2db5d15 100644 --- a/src/adcp/types/generated_poc/a2ui/bound_value.py +++ b/src/adcp/types/generated_poc/a2ui/bound_value.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: a2ui/bound_value.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/a2ui/component.py b/src/adcp/types/generated_poc/a2ui/component.py index 6edec3bc..425c4a10 100644 --- a/src/adcp/types/generated_poc/a2ui/component.py +++ b/src/adcp/types/generated_poc/a2ui/component.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: a2ui/component.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/a2ui/si_catalog.py b/src/adcp/types/generated_poc/a2ui/si_catalog.py index dae2f9bd..d67f4912 100644 --- a/src/adcp/types/generated_poc/a2ui/si_catalog.py +++ b/src/adcp/types/generated_poc/a2ui/si_catalog.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: a2ui/si_catalog.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/a2ui/surface.py b/src/adcp/types/generated_poc/a2ui/surface.py index 62d65dd9..d5dab00c 100644 --- a/src/adcp/types/generated_poc/a2ui/surface.py +++ b/src/adcp/types/generated_poc/a2ui/surface.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: a2ui/surface.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/a2ui/user_action.py b/src/adcp/types/generated_poc/a2ui/user_action.py index a27eb02d..0b087974 100644 --- a/src/adcp/types/generated_poc/a2ui/user_action.py +++ b/src/adcp/types/generated_poc/a2ui/user_action.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: a2ui/user_action.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/get_account_financials_request.py b/src/adcp/types/generated_poc/account/get_account_financials_request.py index fd02b91a..39e19426 100644 --- a/src/adcp/types/generated_poc/account/get_account_financials_request.py +++ b/src/adcp/types/generated_poc/account/get_account_financials_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/get_account_financials_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/get_account_financials_response.py b/src/adcp/types/generated_poc/account/get_account_financials_response.py index 7b68de7f..f7530ddd 100644 --- a/src/adcp/types/generated_poc/account/get_account_financials_response.py +++ b/src/adcp/types/generated_poc/account/get_account_financials_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/get_account_financials_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/list_accounts_request.py b/src/adcp/types/generated_poc/account/list_accounts_request.py index 3588d9a7..7d450312 100644 --- a/src/adcp/types/generated_poc/account/list_accounts_request.py +++ b/src/adcp/types/generated_poc/account/list_accounts_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/list_accounts_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/list_accounts_response.py b/src/adcp/types/generated_poc/account/list_accounts_response.py index aadde995..c1eeb1fd 100644 --- a/src/adcp/types/generated_poc/account/list_accounts_response.py +++ b/src/adcp/types/generated_poc/account/list_accounts_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/list_accounts_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/report_usage_request.py b/src/adcp/types/generated_poc/account/report_usage_request.py index d99369b4..99bdb1e9 100644 --- a/src/adcp/types/generated_poc/account/report_usage_request.py +++ b/src/adcp/types/generated_poc/account/report_usage_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/report_usage_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/report_usage_response.py b/src/adcp/types/generated_poc/account/report_usage_response.py index df82198f..a36fd304 100644 --- a/src/adcp/types/generated_poc/account/report_usage_response.py +++ b/src/adcp/types/generated_poc/account/report_usage_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/report_usage_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/sync_accounts_request.py b/src/adcp/types/generated_poc/account/sync_accounts_request.py index 1d2e9baa..e2cc4f80 100644 --- a/src/adcp/types/generated_poc/account/sync_accounts_request.py +++ b/src/adcp/types/generated_poc/account/sync_accounts_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/sync_accounts_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/sync_accounts_response.py b/src/adcp/types/generated_poc/account/sync_accounts_response.py index 39f105ff..18e532b0 100644 --- a/src/adcp/types/generated_poc/account/sync_accounts_response.py +++ b/src/adcp/types/generated_poc/account/sync_accounts_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/sync_accounts_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/sync_governance_request.py b/src/adcp/types/generated_poc/account/sync_governance_request.py index be02ff23..e30e5b35 100644 --- a/src/adcp/types/generated_poc/account/sync_governance_request.py +++ b/src/adcp/types/generated_poc/account/sync_governance_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/sync_governance_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/account/sync_governance_response.py b/src/adcp/types/generated_poc/account/sync_governance_response.py index 2e97031b..0ea650d5 100644 --- a/src/adcp/types/generated_poc/account/sync_governance_response.py +++ b/src/adcp/types/generated_poc/account/sync_governance_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: account/sync_governance_response.json -# timestamp: 2026-04-18T20:45:21+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/adagents.py b/src/adcp/types/generated_poc/adagents.py index 5cd0d35b..5a999e99 100644 --- a/src/adcp/types/generated_poc/adagents.py +++ b/src/adcp/types/generated_poc/adagents.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: adagents.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -174,7 +174,7 @@ class AuthorizedAgents(AdCPBaseModel): authorization_type: Annotated[ Literal["property_ids"], Field(description="Discriminator indicating authorization by specific property IDs"), - ] + ] = "property_ids" property_ids: Annotated[ list[property_id.PropertyId], Field( @@ -261,7 +261,7 @@ class AuthorizedAgents1(AdCPBaseModel): authorization_type: Annotated[ Literal["property_tags"], Field(description="Discriminator indicating authorization by property tags"), - ] + ] = "property_tags" property_tags: Annotated[ list[property_tag.PropertyTag], Field( @@ -350,7 +350,7 @@ class AuthorizedAgents3(AdCPBaseModel): Field( description="Discriminator indicating authorization for properties from other publisher domains" ), - ] + ] = "publisher_properties" publisher_properties: Annotated[ list[publisher_property_selector.PublisherPropertySelector], Field( @@ -437,7 +437,7 @@ class AuthorizedAgents4(AdCPBaseModel): authorization_type: Annotated[ Literal["signal_ids"], Field(description="Discriminator indicating authorization by specific signal IDs"), - ] + ] = "signal_ids" signal_ids: Annotated[ list[SignalId], Field( @@ -477,7 +477,7 @@ class AuthorizedAgents5(AdCPBaseModel): authorization_type: Annotated[ Literal["signal_tags"], Field(description="Discriminator indicating authorization by signal tags"), - ] + ] = "signal_tags" signal_tags: Annotated[ list[SignalTag], Field( @@ -517,7 +517,7 @@ class AuthorizedAgents2(AdCPBaseModel): authorization_type: Annotated[ Literal["inline_properties"], Field(description="Discriminator indicating authorization by inline property definitions"), - ] + ] = "inline_properties" properties: Annotated[ list[property.Property], Field( diff --git a/src/adcp/types/generated_poc/brand/__init__.py b/src/adcp/types/generated_poc/brand/__init__.py index 9b480fea..1e83c6ed 100644 --- a/src/adcp/types/generated_poc/brand/__init__.py +++ b/src/adcp/types/generated_poc/brand/__init__.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/acquire_rights_request.py b/src/adcp/types/generated_poc/brand/acquire_rights_request.py index 15bc2484..a04c4c70 100644 --- a/src/adcp/types/generated_poc/brand/acquire_rights_request.py +++ b/src/adcp/types/generated_poc/brand/acquire_rights_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/acquire_rights_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/acquire_rights_response.py b/src/adcp/types/generated_poc/brand/acquire_rights_response.py index edc1c86a..10461df4 100644 --- a/src/adcp/types/generated_poc/brand/acquire_rights_response.py +++ b/src/adcp/types/generated_poc/brand/acquire_rights_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/acquire_rights_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -35,7 +35,7 @@ class AcquireRightsResponse2(AdCPBaseModel): status: Annotated[ Literal["pending_approval"], Field(description="Rights require approval from the rights holder"), - ] + ] = "pending_approval" brand_id: str detail: Annotated[str | None, Field(description="Explanation of what requires approval")] = None estimated_response_time: Annotated[ @@ -51,7 +51,9 @@ class AcquireRightsResponse3(AdCPBaseModel): extra="allow", ) rights_id: str - status: Annotated[Literal["rejected"], Field(description="Rights request was rejected")] + status: Annotated[Literal["rejected"], Field(description="Rights request was rejected")] = ( + "rejected" + ) brand_id: str reason: Annotated[ str, @@ -85,7 +87,7 @@ class AcquireRightsResponse1(AdCPBaseModel): rights_id: Annotated[str, Field(description="Rights grant identifier")] status: Annotated[ Literal["acquired"], Field(description="Rights have been cleared and credentials issued") - ] + ] = "acquired" brand_id: Annotated[str, Field(description="Brand identifier of the rights subject")] terms: Annotated[rights_terms.RightsTerms, Field(description="Agreed contractual terms")] generation_credentials: Annotated[ diff --git a/src/adcp/types/generated_poc/brand/creative_approval_request.py b/src/adcp/types/generated_poc/brand/creative_approval_request.py index f2ec3dd0..6da68c8b 100644 --- a/src/adcp/types/generated_poc/brand/creative_approval_request.py +++ b/src/adcp/types/generated_poc/brand/creative_approval_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/creative_approval_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/creative_approval_response.py b/src/adcp/types/generated_poc/brand/creative_approval_response.py index 98b5f7fd..7ab11f69 100644 --- a/src/adcp/types/generated_poc/brand/creative_approval_response.py +++ b/src/adcp/types/generated_poc/brand/creative_approval_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/creative_approval_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -20,7 +20,7 @@ class CreativeApprovalResponse1(AdCPBaseModel): ) status: Annotated[ Literal["approved"], Field(description="Creative has been approved for distribution") - ] + ] = "approved" rights_id: str creative_id: Annotated[ str | None, Field(description="Echo of the buyer's creative identifier") @@ -39,7 +39,7 @@ class CreativeApprovalResponse2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - status: Annotated[Literal["rejected"], Field(description="Creative was rejected")] + status: Annotated[Literal["rejected"], Field(description="Creative was rejected")] = "rejected" rights_id: str creative_id: Annotated[ str | None, Field(description="Echo of the buyer's creative identifier") @@ -60,7 +60,9 @@ class CreativeApprovalResponse3(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - status: Annotated[Literal["pending_review"], Field(description="Creative is queued for review")] + status: Annotated[ + Literal["pending_review"], Field(description="Creative is queued for review") + ] = "pending_review" rights_id: str creative_id: Annotated[ str | None, Field(description="Echo of the buyer's creative identifier") diff --git a/src/adcp/types/generated_poc/brand/get_brand_identity_request.py b/src/adcp/types/generated_poc/brand/get_brand_identity_request.py index 3965668b..bcfda85f 100644 --- a/src/adcp/types/generated_poc/brand/get_brand_identity_request.py +++ b/src/adcp/types/generated_poc/brand/get_brand_identity_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/get_brand_identity_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/get_brand_identity_response.py b/src/adcp/types/generated_poc/brand/get_brand_identity_response.py index 29e1f76c..26719168 100644 --- a/src/adcp/types/generated_poc/brand/get_brand_identity_response.py +++ b/src/adcp/types/generated_poc/brand/get_brand_identity_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/get_brand_identity_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/get_rights_request.py b/src/adcp/types/generated_poc/brand/get_rights_request.py index 2b5ceff6..8599c02d 100644 --- a/src/adcp/types/generated_poc/brand/get_rights_request.py +++ b/src/adcp/types/generated_poc/brand/get_rights_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/get_rights_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/get_rights_response.py b/src/adcp/types/generated_poc/brand/get_rights_response.py index fb361c66..83e5590f 100644 --- a/src/adcp/types/generated_poc/brand/get_rights_response.py +++ b/src/adcp/types/generated_poc/brand/get_rights_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/get_rights_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/revocation_notification.py b/src/adcp/types/generated_poc/brand/revocation_notification.py index 01114629..41c9b3fc 100644 --- a/src/adcp/types/generated_poc/brand/revocation_notification.py +++ b/src/adcp/types/generated_poc/brand/revocation_notification.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/revocation_notification.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/rights_pricing_option.py b/src/adcp/types/generated_poc/brand/rights_pricing_option.py index 33bbad43..7510929d 100644 --- a/src/adcp/types/generated_poc/brand/rights_pricing_option.py +++ b/src/adcp/types/generated_poc/brand/rights_pricing_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/rights_pricing_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/rights_terms.py b/src/adcp/types/generated_poc/brand/rights_terms.py index 7876a88e..8a4d1b4a 100644 --- a/src/adcp/types/generated_poc/brand/rights_terms.py +++ b/src/adcp/types/generated_poc/brand/rights_terms.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/rights_terms.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/update_rights_request.py b/src/adcp/types/generated_poc/brand/update_rights_request.py index f046d38e..3f36d9c5 100644 --- a/src/adcp/types/generated_poc/brand/update_rights_request.py +++ b/src/adcp/types/generated_poc/brand/update_rights_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/update_rights_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/brand/update_rights_response.py b/src/adcp/types/generated_poc/brand/update_rights_response.py index c79f70b3..741b6620 100644 --- a/src/adcp/types/generated_poc/brand/update_rights_response.py +++ b/src/adcp/types/generated_poc/brand/update_rights_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand/update_rights_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_request.py b/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_request.py index ec31cc23..26b8733d 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_request.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/calibrate_content_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -336,7 +336,7 @@ class Provenance(AdCPBaseModel): class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -920,7 +920,7 @@ class Identifiers(AdCPBaseModel): class AssetAccess4(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -930,7 +930,7 @@ class Provider(Enum): class AssetAccess5(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -938,7 +938,7 @@ class AssetAccess5(AdCPBaseModel): class AssetAccess6(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess4 | AssetAccess5 | AssetAccess6]): @@ -955,7 +955,7 @@ def __getattr__(self, name: str) -> Any: class Assets53(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -974,7 +974,7 @@ class Assets53(AdCPBaseModel): class Assets54(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1007,7 +1007,7 @@ class Assets54(AdCPBaseModel): class Assets55(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_response.py b/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_response.py index 2871526b..5bcfc8eb 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_response.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/calibrate_content_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/calibrate_content_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_request.py b/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_request.py index 029d0448..2c8d29bf 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_request.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/create_content_standards_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -86,7 +86,7 @@ class GovernanceDomain(Enum): class Pass(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( @@ -423,7 +423,7 @@ class Provenance(AdCPBaseModel): class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1007,7 +1007,7 @@ class Identifiers(AdCPBaseModel): class Fail(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( @@ -1144,7 +1144,7 @@ class Provenance53(AdCPBaseModel): class Assets60(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1690,7 +1690,7 @@ class Exemplar(AdCPBaseModel): class AssetAccess7(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -1700,7 +1700,7 @@ class Provider(Enum): class AssetAccess8(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -1708,7 +1708,7 @@ class AssetAccess8(AdCPBaseModel): class AssetAccess9(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess7 | AssetAccess8 | AssetAccess9]): @@ -1868,7 +1868,7 @@ class Policy(AdCPBaseModel): class Assets57(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1887,7 +1887,7 @@ class Assets57(AdCPBaseModel): class Assets58(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1920,7 +1920,7 @@ class Assets58(AdCPBaseModel): class Assets59(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2016,7 +2016,7 @@ class Pass2(AdCPBaseModel): class Assets61(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2035,7 +2035,7 @@ class Assets61(AdCPBaseModel): class Assets62(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2068,7 +2068,7 @@ class Assets62(AdCPBaseModel): class Assets63(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_response.py b/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_response.py index d74097d1..ceadae0c 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_response.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/create_content_standards_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/create_content_standards_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_request.py b/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_request.py index b7d082c7..c1f6731f 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_request.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/get_content_standards_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_response.py b/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_response.py index 7c8099d3..ef5da01e 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_response.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/get_content_standards_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/get_content_standards_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -383,7 +383,7 @@ class Provenance(AdCPBaseModel): class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1091,7 +1091,7 @@ class Provenance77(AdCPBaseModel): class Assets111(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1629,7 +1629,7 @@ class PricingOption121(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -1645,7 +1645,7 @@ class PricingOption122(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -1680,7 +1680,7 @@ class PricingOption123(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -1697,7 +1697,7 @@ class PricingOption124(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -1732,7 +1732,7 @@ class PricingOption125(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( @@ -1892,7 +1892,7 @@ class Exemplar(AdCPBaseModel): class AssetAccess10(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -1902,7 +1902,7 @@ class Provider(Enum): class AssetAccess11(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -1910,7 +1910,7 @@ class AssetAccess11(AdCPBaseModel): class AssetAccess12(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess10 | AssetAccess11 | AssetAccess12]): @@ -2070,7 +2070,7 @@ class Policy(AdCPBaseModel): class Assets108(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2089,7 +2089,7 @@ class Assets108(AdCPBaseModel): class Assets109(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2122,7 +2122,7 @@ class Assets109(AdCPBaseModel): class Assets110(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2218,7 +2218,7 @@ class Pas(AdCPBaseModel): class Assets112(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2237,7 +2237,7 @@ class Assets112(AdCPBaseModel): class Assets113(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2270,7 +2270,7 @@ class Assets113(AdCPBaseModel): class Assets114(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_request.py b/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_request.py index dfd0f827..33429955 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_request.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/get_media_buy_artifacts_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_response.py b/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_response.py index f309c1bb..b71cc1d8 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_response.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/get_media_buy_artifacts_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/get_media_buy_artifacts_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -336,7 +336,7 @@ class Provenance(AdCPBaseModel): class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1034,7 +1034,7 @@ class GetMediaBuyArtifactsResponse4(AdCPBaseModel): class AssetAccess13(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -1044,7 +1044,7 @@ class Provider(Enum): class AssetAccess14(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -1052,7 +1052,7 @@ class AssetAccess14(AdCPBaseModel): class AssetAccess15(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess13 | AssetAccess14 | AssetAccess15]): @@ -1069,7 +1069,7 @@ def __getattr__(self, name: str) -> Any: class Assets148(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1088,7 +1088,7 @@ class Assets148(AdCPBaseModel): class Assets149(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1121,7 +1121,7 @@ class Assets149(AdCPBaseModel): class Assets150(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_request.py b/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_request.py index d1da54a9..542ae3d2 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_request.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/list_content_standards_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_response.py b/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_response.py index 1905123d..55a09922 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_response.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/list_content_standards_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/list_content_standards_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -383,7 +383,7 @@ class Provenance(AdCPBaseModel): class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1091,7 +1091,7 @@ class Provenance120(AdCPBaseModel): class Assets155(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1629,7 +1629,7 @@ class PricingOption151(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -1645,7 +1645,7 @@ class PricingOption152(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -1680,7 +1680,7 @@ class PricingOption153(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -1697,7 +1697,7 @@ class PricingOption154(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -1732,7 +1732,7 @@ class PricingOption155(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( @@ -1914,7 +1914,7 @@ class Exemplar(AdCPBaseModel): class AssetAccess16(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -1924,7 +1924,7 @@ class Provider(Enum): class AssetAccess17(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -1932,7 +1932,7 @@ class AssetAccess17(AdCPBaseModel): class AssetAccess18(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess16 | AssetAccess17 | AssetAccess18]): @@ -2092,7 +2092,7 @@ class Policy(AdCPBaseModel): class Assets152(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2111,7 +2111,7 @@ class Assets152(AdCPBaseModel): class Assets153(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2144,7 +2144,7 @@ class Assets153(AdCPBaseModel): class Assets154(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2240,7 +2240,7 @@ class Pas(AdCPBaseModel): class Assets156(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2259,7 +2259,7 @@ class Assets156(AdCPBaseModel): class Assets157(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2292,7 +2292,7 @@ class Assets157(AdCPBaseModel): class Assets158(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_request.py b/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_request.py index b0eaeb16..1fe24f02 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_request.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/update_content_standards_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -86,7 +86,7 @@ class GovernanceDomain(Enum): class Pass(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( @@ -423,7 +423,7 @@ class Provenance(AdCPBaseModel): class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1007,7 +1007,7 @@ class Identifiers(AdCPBaseModel): class Fail(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( @@ -1144,7 +1144,7 @@ class Provenance213(AdCPBaseModel): class Assets313(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -1690,7 +1690,7 @@ class Exemplar(AdCPBaseModel): class AssetAccess19(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -1700,7 +1700,7 @@ class Provider(Enum): class AssetAccess20(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -1708,7 +1708,7 @@ class AssetAccess20(AdCPBaseModel): class AssetAccess21(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess19 | AssetAccess20 | AssetAccess21]): @@ -1868,7 +1868,7 @@ class Policy(AdCPBaseModel): class Assets310(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1887,7 +1887,7 @@ class Assets310(AdCPBaseModel): class Assets311(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1920,7 +1920,7 @@ class Assets311(AdCPBaseModel): class Assets312(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2016,7 +2016,7 @@ class Pass5(AdCPBaseModel): class Assets314(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2035,7 +2035,7 @@ class Assets314(AdCPBaseModel): class Assets315(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -2068,7 +2068,7 @@ class Assets315(AdCPBaseModel): class Assets316(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_response.py b/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_response.py index ab72d90c..a6ee570d 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_response.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/update_content_standards_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/update_content_standards_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_request.py b/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_request.py index 993b6308..6c4e6c8d 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_request.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/validate_content_delivery_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -336,7 +336,7 @@ class Provenance(AdCPBaseModel): class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -925,7 +925,7 @@ class BrandContext(AdCPBaseModel): class AssetAccess22(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -935,7 +935,7 @@ class Provider(Enum): class AssetAccess23(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -943,7 +943,7 @@ class AssetAccess23(AdCPBaseModel): class AssetAccess24(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess22 | AssetAccess23 | AssetAccess24]): @@ -960,7 +960,7 @@ def __getattr__(self, name: str) -> Any: class Assets350(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -979,7 +979,7 @@ class Assets350(AdCPBaseModel): class Assets351(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -1012,7 +1012,7 @@ class Assets351(AdCPBaseModel): class Assets352(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_response.py b/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_response.py index 3d217760..f4a44e50 100644 --- a/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_response.py +++ b/src/adcp/types/generated_poc/bundled/content_standards/validate_content_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/content_standards/validate_content_delivery_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/core/tasks_get_request.py b/src/adcp/types/generated_poc/bundled/core/tasks_get_request.py index a96e4a9c..9a82610a 100644 --- a/src/adcp/types/generated_poc/bundled/core/tasks_get_request.py +++ b/src/adcp/types/generated_poc/bundled/core/tasks_get_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/core/tasks_get_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/core/tasks_get_response.py b/src/adcp/types/generated_poc/bundled/core/tasks_get_response.py index 0e0b3d18..7647a6a0 100644 --- a/src/adcp/types/generated_poc/bundled/core/tasks_get_response.py +++ b/src/adcp/types/generated_poc/bundled/core/tasks_get_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/core/tasks_get_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/core/tasks_list_request.py b/src/adcp/types/generated_poc/bundled/core/tasks_list_request.py index 0208914c..348a9d5b 100644 --- a/src/adcp/types/generated_poc/bundled/core/tasks_list_request.py +++ b/src/adcp/types/generated_poc/bundled/core/tasks_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/core/tasks_list_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/core/tasks_list_response.py b/src/adcp/types/generated_poc/bundled/core/tasks_list_response.py index b324e093..dfb38eb6 100644 --- a/src/adcp/types/generated_poc/bundled/core/tasks_list_response.py +++ b/src/adcp/types/generated_poc/bundled/core/tasks_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/core/tasks_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_request.py b/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_request.py index 4771f2f1..62b0a5d3 100644 --- a/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_request.py +++ b/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/get_creative_delivery_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_response.py b/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_response.py index 79e9565c..adaf155f 100644 --- a/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_response.py +++ b/src/adcp/types/generated_poc/bundled/creative/get_creative_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/get_creative_delivery_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -678,6 +678,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -883,6 +889,12 @@ class Assets116(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -1096,6 +1108,12 @@ class Assets117(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -1304,11 +1322,12 @@ class Assets118(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1336,6 +1355,11 @@ class Assets118(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy85(DeclaredBy): @@ -1466,11 +1490,12 @@ class Assets119(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1498,6 +1523,11 @@ class Assets119(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy86(DeclaredBy): @@ -1628,6 +1658,12 @@ class Assets120(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1775,7 +1811,18 @@ class Assets121(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -1941,6 +1988,12 @@ class Assets122(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -2090,6 +2143,12 @@ class Assets123(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -2338,6 +2397,12 @@ class Assets124(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2500,6 +2565,12 @@ class Assets125(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2672,11 +2743,12 @@ class Assets126(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2700,6 +2772,11 @@ class Assets126(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy93(DeclaredBy): @@ -2830,11 +2907,12 @@ class Assets127(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2858,6 +2936,11 @@ class Assets127(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -2869,6 +2952,12 @@ class Assets128(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -3051,6 +3140,12 @@ class Assets129(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -3285,6 +3380,12 @@ class Assets130(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class RightsAgent(AdCPBaseModel): @@ -3576,7 +3677,7 @@ class Manifest(AdCPBaseModel): | Assets130, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/creative/get_creative_features_request.py b/src/adcp/types/generated_poc/bundled/creative/get_creative_features_request.py index 3d484dcd..f0695f8a 100644 --- a/src/adcp/types/generated_poc/bundled/creative/get_creative_features_request.py +++ b/src/adcp/types/generated_poc/bundled/creative/get_creative_features_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/get_creative_features_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -330,6 +330,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -535,6 +541,12 @@ class Assets132(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -748,6 +760,12 @@ class Assets133(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -956,11 +974,12 @@ class Assets134(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -988,6 +1007,11 @@ class Assets134(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy99(DeclaredBy): @@ -1118,11 +1142,12 @@ class Assets135(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1150,6 +1175,11 @@ class Assets135(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy100(DeclaredBy): @@ -1280,6 +1310,12 @@ class Assets136(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1427,7 +1463,18 @@ class Assets137(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -1593,6 +1640,12 @@ class Assets138(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -1742,6 +1795,12 @@ class Assets139(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -1990,6 +2049,12 @@ class Assets140(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2152,6 +2217,12 @@ class Assets141(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2324,11 +2395,12 @@ class Assets142(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2352,6 +2424,11 @@ class Assets142(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy107(DeclaredBy): @@ -2482,11 +2559,12 @@ class Assets143(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2510,6 +2588,11 @@ class Assets143(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -2521,6 +2604,12 @@ class Assets144(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -2703,6 +2792,12 @@ class Assets145(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -2968,6 +3063,12 @@ class Assets146(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class RightsAgent(AdCPBaseModel): @@ -3259,7 +3360,7 @@ class CreativeManifest(AdCPBaseModel): | Assets146, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/creative/get_creative_features_response.py b/src/adcp/types/generated_poc/bundled/creative/get_creative_features_response.py index 6104b81c..bec0c0f3 100644 --- a/src/adcp/types/generated_poc/bundled/creative/get_creative_features_response.py +++ b/src/adcp/types/generated_poc/bundled/creative/get_creative_features_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/get_creative_features_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_request.py b/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_request.py index 730285a4..649e1ca5 100644 --- a/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_request.py +++ b/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/list_creative_formats_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_response.py b/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_response.py index bae6152b..95617491 100644 --- a/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_response.py +++ b/src/adcp/types/generated_poc/bundled/creative/list_creative_formats_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/list_creative_formats_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -1260,7 +1260,7 @@ class PricingOption171(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -1276,7 +1276,7 @@ class PricingOption172(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -1311,7 +1311,7 @@ class PricingOption173(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -1328,7 +1328,7 @@ class PricingOption174(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -1363,7 +1363,7 @@ class PricingOption175(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( @@ -1542,7 +1542,7 @@ class ScalarBinding(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["scalar"] + kind: Literal["scalar"] = "scalar" asset_id: Annotated[ str, Field( @@ -1568,7 +1568,7 @@ class AssetPoolBinding(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["asset_pool"] + kind: Literal["asset_pool"] = "asset_pool" asset_id: Annotated[ str, Field( @@ -1725,7 +1725,7 @@ class BaseIndividualAsset(AdCPBaseModel): item_type: Annotated[ Literal["individual"], Field(description="Discriminator indicating this is an individual asset"), - ] + ] = "individual" asset_id: Annotated[ str, Field( @@ -1901,7 +1901,7 @@ class FieldBindings(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["catalog_group"] + kind: Literal["catalog_group"] = "catalog_group" format_group_id: Annotated[ str, Field(description="The asset_group_id of a repeatable_group in the format's assets array."), @@ -2130,7 +2130,7 @@ class Assets200(AdCPBaseModel): item_type: Annotated[ Literal["repeatable_group"], Field(description="Discriminator indicating this is a repeatable asset group"), - ] + ] = "repeatable_group" asset_group_id: Annotated[ str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')") ] diff --git a/src/adcp/types/generated_poc/bundled/creative/list_creatives_request.py b/src/adcp/types/generated_poc/bundled/creative/list_creatives_request.py index 08bd8a3d..e5944d46 100644 --- a/src/adcp/types/generated_poc/bundled/creative/list_creatives_request.py +++ b/src/adcp/types/generated_poc/bundled/creative/list_creatives_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/list_creatives_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/creative/list_creatives_response.py b/src/adcp/types/generated_poc/bundled/creative/list_creatives_response.py index 1a0eca88..784036b6 100644 --- a/src/adcp/types/generated_poc/bundled/creative/list_creatives_response.py +++ b/src/adcp/types/generated_poc/bundled/creative/list_creatives_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/list_creatives_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -598,7 +598,7 @@ class FormatId(AdCPBaseModel): ] = None -class Status22(Enum): +class Status26(Enum): processing = "processing" pending_review = "pending_review" approved = "approved" @@ -877,6 +877,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -1082,6 +1088,12 @@ class Assets214(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -1295,6 +1307,12 @@ class Assets215(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -1503,11 +1521,12 @@ class Assets216(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1535,6 +1554,11 @@ class Assets216(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy128(DeclaredBy): @@ -1665,11 +1689,12 @@ class Assets217(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1697,6 +1722,11 @@ class Assets217(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy129(DeclaredBy): @@ -1827,6 +1857,12 @@ class Assets218(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1974,7 +2010,18 @@ class Assets219(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -2140,6 +2187,12 @@ class Assets220(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -2289,6 +2342,12 @@ class Assets221(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -2537,6 +2596,12 @@ class Assets222(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2699,6 +2764,12 @@ class Assets223(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2871,11 +2942,12 @@ class Assets224(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2899,6 +2971,11 @@ class Assets224(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy136(DeclaredBy): @@ -3029,11 +3106,12 @@ class Assets225(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -3057,6 +3135,11 @@ class Assets225(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -3068,6 +3151,12 @@ class Assets226(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -3250,6 +3339,12 @@ class Assets227(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -3515,6 +3610,12 @@ class Assets228(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class VariableType(Enum): @@ -3616,7 +3717,7 @@ class Items(AdCPBaseModel): asset_kind: Annotated[ Literal["media"], Field(description="Discriminator indicating this is a media asset with content_uri"), - ] + ] = "media" asset_type: Annotated[ str, Field( @@ -3636,7 +3737,7 @@ class Items1(AdCPBaseModel): asset_kind: Annotated[ Literal["text"], Field(description="Discriminator indicating this is a text asset with content"), - ] + ] = "text" asset_type: Annotated[ str, Field( @@ -3658,7 +3759,7 @@ class PricingOption181(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -3674,7 +3775,7 @@ class PricingOption182(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -3709,7 +3810,7 @@ class PricingOption183(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -3726,7 +3827,7 @@ class PricingOption184(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -3761,7 +3862,7 @@ class PricingOption185(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( @@ -3975,7 +4076,7 @@ class Creative(AdCPBaseModel): ), ] status: Annotated[ - Status22, + Status26, Field(description="Current approval status of the creative", title="Creative Status"), ] created_date: Annotated[AwareDatetime, Field(description="When the creative was created")] @@ -4001,7 +4102,9 @@ class Creative(AdCPBaseModel): | Assets228, ] | None, - Field(description="Assets for this creative, keyed by asset_id"), + Field( + description="Assets for this creative, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] = None tags: Annotated[ list[str] | None, Field(description="User-defined tags for organization and searchability") diff --git a/src/adcp/types/generated_poc/bundled/creative/preview_creative_request.py b/src/adcp/types/generated_poc/bundled/creative/preview_creative_request.py index ac810aa2..499e29b1 100644 --- a/src/adcp/types/generated_poc/bundled/creative/preview_creative_request.py +++ b/src/adcp/types/generated_poc/bundled/creative/preview_creative_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/preview_creative_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -328,6 +328,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -533,6 +539,12 @@ class Assets246(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -746,6 +758,12 @@ class Assets247(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -954,11 +972,12 @@ class Assets248(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -986,6 +1005,11 @@ class Assets248(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy155(DeclaredBy): @@ -1116,11 +1140,12 @@ class Assets249(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1148,6 +1173,11 @@ class Assets249(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy156(DeclaredBy): @@ -1278,6 +1308,12 @@ class Assets250(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1425,7 +1461,18 @@ class Assets251(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -1591,6 +1638,12 @@ class Assets252(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -1740,6 +1793,12 @@ class Assets253(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -1988,6 +2047,12 @@ class Assets254(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2150,6 +2215,12 @@ class Assets255(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2322,11 +2393,12 @@ class Assets256(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2350,6 +2422,11 @@ class Assets256(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy163(DeclaredBy): @@ -2480,11 +2557,12 @@ class Assets257(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2508,6 +2586,11 @@ class Assets257(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -2519,6 +2602,12 @@ class Assets258(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -2701,6 +2790,12 @@ class Assets259(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -2966,6 +3061,12 @@ class Assets260(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class RightsAgent(AdCPBaseModel): @@ -3257,7 +3358,7 @@ class CreativeManifest(AdCPBaseModel): | Assets260, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ @@ -3450,6 +3551,12 @@ class Assets261(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -3594,6 +3701,12 @@ class Assets262(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -3807,6 +3920,12 @@ class Assets263(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -3972,11 +4091,12 @@ class Assets264(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -4004,6 +4124,11 @@ class Assets264(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy169(DeclaredBy): @@ -4134,11 +4259,12 @@ class Assets265(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -4166,6 +4292,11 @@ class Assets265(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy170(DeclaredBy): @@ -4296,6 +4427,12 @@ class Assets266(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -4437,7 +4574,18 @@ class Assets267(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -4585,6 +4733,12 @@ class Assets268(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -4728,6 +4882,12 @@ class Assets269(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -4878,6 +5038,12 @@ class Assets270(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -5040,6 +5206,12 @@ class Assets271(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -5181,11 +5353,12 @@ class Assets272(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -5209,6 +5382,11 @@ class Assets272(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy177(DeclaredBy): @@ -5339,11 +5517,12 @@ class Assets273(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -5367,6 +5546,11 @@ class Assets273(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class Assets274(Assets258): @@ -5484,6 +5668,12 @@ class Assets275(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class FeedFieldMapping13(FeedFieldMapping): @@ -5591,6 +5781,12 @@ class Assets276(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class Right7(Right): @@ -5757,7 +5953,7 @@ class CreativeManifest6(AdCPBaseModel): | Assets276, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/creative/preview_creative_response.py b/src/adcp/types/generated_poc/bundled/creative/preview_creative_response.py index 4a270d77..c4113349 100644 --- a/src/adcp/types/generated_poc/bundled/creative/preview_creative_response.py +++ b/src/adcp/types/generated_poc/bundled/creative/preview_creative_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/preview_creative_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -43,7 +43,7 @@ class Renders(AdCPBaseModel): ] output_format: Annotated[ Literal["url"], Field(description="Discriminator indicating preview_url is provided") - ] + ] = "url" preview_url: Annotated[ AnyUrl, Field( @@ -74,7 +74,7 @@ class Renders13(AdCPBaseModel): ] output_format: Annotated[ Literal["html"], Field(description="Discriminator indicating preview_html is provided") - ] + ] = "html" preview_html: Annotated[ str, Field( @@ -107,7 +107,7 @@ class Renders14(AdCPBaseModel): Field( description="Discriminator indicating both preview_url and preview_html are provided" ), - ] + ] = "both" preview_url: Annotated[ AnyUrl, Field( @@ -169,7 +169,7 @@ class PreviewCreativeResponse4(AdCPBaseModel): response_type: Annotated[ Literal["single"], Field(description="Discriminator indicating this is a single preview response"), - ] + ] = "single" previews: Annotated[ list[Preview], Field( @@ -344,7 +344,7 @@ class PreviewCreativeResponse5(AdCPBaseModel): response_type: Annotated[ Literal["batch"], Field(description="Discriminator indicating this is a batch preview response"), - ] + ] = "batch" results: Annotated[ list[Results | Results3], Field( @@ -699,6 +699,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -904,6 +910,12 @@ class Assets278(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -1117,6 +1129,12 @@ class Assets279(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -1325,11 +1343,12 @@ class Assets280(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1357,6 +1376,11 @@ class Assets280(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy183(DeclaredBy): @@ -1487,11 +1511,12 @@ class Assets281(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1519,6 +1544,11 @@ class Assets281(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy184(DeclaredBy): @@ -1649,6 +1679,12 @@ class Assets282(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1796,7 +1832,18 @@ class Assets283(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -1962,6 +2009,12 @@ class Assets284(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -2111,6 +2164,12 @@ class Assets285(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -2359,6 +2418,12 @@ class Assets286(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2521,6 +2586,12 @@ class Assets287(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2693,11 +2764,12 @@ class Assets288(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2721,6 +2793,11 @@ class Assets288(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy191(DeclaredBy): @@ -2851,11 +2928,12 @@ class Assets289(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2879,6 +2957,11 @@ class Assets289(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -2890,6 +2973,12 @@ class Assets290(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -3072,6 +3161,12 @@ class Assets291(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -3337,6 +3432,12 @@ class Assets292(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class RightsAgent(AdCPBaseModel): @@ -3628,7 +3729,7 @@ class Manifest(AdCPBaseModel): | Assets292, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ @@ -3666,7 +3767,7 @@ class PreviewCreativeResponse6(AdCPBaseModel): response_type: Annotated[ Literal["variant"], Field(description="Discriminator indicating this is a variant preview response"), - ] + ] = "variant" variant_id: Annotated[str, Field(description="Platform-assigned variant identifier")] creative_id: Annotated[ str | None, Field(description="Creative identifier this variant belongs to") diff --git a/src/adcp/types/generated_poc/bundled/creative/sync_creatives_request.py b/src/adcp/types/generated_poc/bundled/creative/sync_creatives_request.py index 43a8d8a5..04ecbd37 100644 --- a/src/adcp/types/generated_poc/bundled/creative/sync_creatives_request.py +++ b/src/adcp/types/generated_poc/bundled/creative/sync_creatives_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/sync_creatives_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -425,6 +425,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -630,6 +636,12 @@ class Assets294(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -843,6 +855,12 @@ class Assets295(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -1051,11 +1069,12 @@ class Assets296(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1083,6 +1102,11 @@ class Assets296(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy198(DeclaredBy): @@ -1213,11 +1237,12 @@ class Assets297(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1245,6 +1270,11 @@ class Assets297(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy199(DeclaredBy): @@ -1375,6 +1405,12 @@ class Assets298(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1522,7 +1558,18 @@ class Assets299(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -1688,6 +1735,12 @@ class Assets300(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -1837,6 +1890,12 @@ class Assets301(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -2085,6 +2144,12 @@ class Assets302(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2247,6 +2312,12 @@ class Assets303(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2419,11 +2490,12 @@ class Assets304(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2447,6 +2519,11 @@ class Assets304(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy206(DeclaredBy): @@ -2577,11 +2654,12 @@ class Assets305(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2605,6 +2683,11 @@ class Assets305(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -2616,6 +2699,12 @@ class Assets306(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -2798,6 +2887,12 @@ class Assets307(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -3063,6 +3158,12 @@ class Assets308(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class Input(AdCPBaseModel): @@ -3268,7 +3369,9 @@ class Creative(AdCPBaseModel): | Assets307 | Assets308, ], - Field(description="Assets required by the format, keyed by asset_id"), + Field( + description="Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] inputs: Annotated[ list[Input] | None, diff --git a/src/adcp/types/generated_poc/bundled/creative/sync_creatives_response.py b/src/adcp/types/generated_poc/bundled/creative/sync_creatives_response.py index 16107a95..af79e0dc 100644 --- a/src/adcp/types/generated_poc/bundled/creative/sync_creatives_response.py +++ b/src/adcp/types/generated_poc/bundled/creative/sync_creatives_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/creative/sync_creatives_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -512,7 +512,7 @@ class Action(Enum): deleted = "deleted" -class Status34(Enum): +class Status38(Enum): processing = "processing" pending_review = "pending_review" approved = "approved" @@ -689,7 +689,7 @@ class Creative(AdCPBaseModel): ), ] status: Annotated[ - Status34 | None, + Status38 | None, Field( description="Advisory review-lifecycle state of the creative after this sync — a UI hint and polling-scheduling signal, NOT a spend-authorization gate. Orthogonal to action — action says what the sync did (created, updated, ...); status says where the creative sits in review. Values come from CreativeStatus only (processing, pending_review, approved, rejected, archived) — never from CreativeAction. Sellers with async review return processing or pending_review; sellers with synchronous review MAY return a terminal value (approved, rejected). Buyers MUST NOT gate downstream spend or package activation on status: approved from this response — a compromised or buggy seller could declare approved while bypassing content-policy review. Reconcile via list_creatives or a signed review webhook before committing spend. Authoritative state is always via list_creatives. MUST be omitted when action is failed or deleted (the creative has no meaningful review state — failure details belong in the errors array; deleted creatives are gone from the library). Omit entirely when the seller has no review lifecycle at all.", title="Creative Status", @@ -812,7 +812,7 @@ class SyncCreativesResponse6(AdCPBaseModel): Field( description="Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose creatives array carries per-item approval state via CreativeStatus. See task-status.json for the full task-status enum." ), - ] + ] = "submitted" task_id: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/bundled/media_buy/build_creative_request.py b/src/adcp/types/generated_poc/bundled/media_buy/build_creative_request.py index 7c5efccf..5d735893 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/build_creative_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/build_creative_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/build_creative_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -330,6 +330,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -535,6 +541,12 @@ class Assets5(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -748,6 +760,12 @@ class Assets6(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -956,11 +974,12 @@ class Assets7(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -988,6 +1007,11 @@ class Assets7(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy4(DeclaredBy): @@ -1118,11 +1142,12 @@ class Assets8(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1150,6 +1175,11 @@ class Assets8(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy5(DeclaredBy): @@ -1280,6 +1310,12 @@ class Assets9(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1427,7 +1463,18 @@ class Assets10(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -1593,6 +1640,12 @@ class Assets11(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -1742,6 +1795,12 @@ class Assets12(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -1990,6 +2049,12 @@ class Assets13(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2152,6 +2217,12 @@ class Assets14(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2324,11 +2395,12 @@ class Assets15(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2352,6 +2424,11 @@ class Assets15(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy12(DeclaredBy): @@ -2482,11 +2559,12 @@ class Assets16(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2510,6 +2588,11 @@ class Assets16(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -2521,6 +2604,12 @@ class Assets17(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -2703,6 +2792,12 @@ class Assets18(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -2968,6 +3063,12 @@ class Assets19(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class RightsAgent(AdCPBaseModel): @@ -3259,7 +3360,7 @@ class CreativeManifest(AdCPBaseModel): | Assets19, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/media_buy/build_creative_response.py b/src/adcp/types/generated_poc/bundled/media_buy/build_creative_response.py index 5c14c0a9..2c2a7aca 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/build_creative_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/build_creative_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/build_creative_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -322,6 +322,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -527,6 +533,12 @@ class Assets21(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -740,6 +752,12 @@ class Assets22(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -948,11 +966,12 @@ class Assets23(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -980,6 +999,11 @@ class Assets23(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy18(DeclaredBy): @@ -1110,11 +1134,12 @@ class Assets24(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -1142,6 +1167,11 @@ class Assets24(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy19(DeclaredBy): @@ -1272,6 +1302,12 @@ class Assets25(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -1419,7 +1455,18 @@ class Assets26(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -1585,6 +1632,12 @@ class Assets27(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -1734,6 +1787,12 @@ class Assets28(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -1982,6 +2041,12 @@ class Assets29(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -2144,6 +2209,12 @@ class Assets30(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -2316,11 +2387,12 @@ class Assets31(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2344,6 +2416,11 @@ class Assets31(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy26(DeclaredBy): @@ -2474,11 +2551,12 @@ class Assets32(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -2502,6 +2580,11 @@ class Assets32(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -2513,6 +2596,12 @@ class Assets33(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -2695,6 +2784,12 @@ class Assets34(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class Type(Enum): @@ -2960,6 +3055,12 @@ class Assets35(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class RightsAgent(AdCPBaseModel): @@ -3251,7 +3352,7 @@ class CreativeManifest(AdCPBaseModel): | Assets35, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ @@ -3314,7 +3415,7 @@ class Renders(AdCPBaseModel): ] output_format: Annotated[ Literal["url"], Field(description="Discriminator indicating preview_url is provided") - ] + ] = "url" preview_url: Annotated[ AnyUrl, Field( @@ -3345,7 +3446,7 @@ class Renders1(AdCPBaseModel): ] output_format: Annotated[ Literal["html"], Field(description="Discriminator indicating preview_html is provided") - ] + ] = "html" preview_html: Annotated[ str, Field( @@ -3378,7 +3479,7 @@ class Renders2(AdCPBaseModel): Field( description="Discriminator indicating both preview_url and preview_html are provided" ), - ] + ] = "both" preview_url: Annotated[ AnyUrl, Field( @@ -3725,6 +3826,12 @@ class Assets36(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -3869,6 +3976,12 @@ class Assets37(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -4082,6 +4195,12 @@ class Assets38(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -4247,11 +4366,12 @@ class Assets39(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -4279,6 +4399,11 @@ class Assets39(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy32(DeclaredBy): @@ -4409,11 +4534,12 @@ class Assets40(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -4441,6 +4567,11 @@ class Assets40(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy33(DeclaredBy): @@ -4571,6 +4702,12 @@ class Assets41(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -4712,7 +4849,18 @@ class Assets42(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -4860,6 +5008,12 @@ class Assets43(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -5003,6 +5157,12 @@ class Assets44(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -5153,6 +5313,12 @@ class Assets45(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -5315,6 +5481,12 @@ class Assets46(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -5456,11 +5628,12 @@ class Assets47(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -5484,6 +5657,11 @@ class Assets47(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy40(DeclaredBy): @@ -5614,11 +5792,12 @@ class Assets48(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -5642,6 +5821,11 @@ class Assets48(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class Assets49(Assets33): @@ -5759,6 +5943,12 @@ class Assets50(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class FeedFieldMapping2(FeedFieldMapping): @@ -5866,6 +6056,12 @@ class Assets51(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class Right2(Right): @@ -6032,7 +6228,7 @@ class CreativeManifest3(AdCPBaseModel): | Assets51, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_request.py b/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_request.py index deaecfe9..c39e482f 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/create_media_buy_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -534,7 +534,7 @@ class Target(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[ float, Field(description="Target cost per metric unit in the buy currency", gt=0.0) ] @@ -544,7 +544,7 @@ class Target1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["threshold_rate"] + kind: Literal["threshold_rate"] = "threshold_rate" value: Annotated[ float, Field( @@ -558,7 +558,7 @@ class OptimizationGoals(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["metric"] + kind: Literal["metric"] = "metric" metric: Annotated[ Metric, Field( @@ -641,7 +641,7 @@ class Target2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[float, Field(description="Target cost per event in the buy currency", gt=0.0)] @@ -649,7 +649,7 @@ class Target3(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["per_ad_spend"] + kind: Literal["per_ad_spend"] = "per_ad_spend" value: Annotated[ float, Field(description="Target return ratio (e.g., 4.0 means $4 of value per $1 spent)", gt=0.0), @@ -660,7 +660,7 @@ class Target4(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["maximize_value"] + kind: Literal["maximize_value"] = "maximize_value" class PostClick(Window): @@ -693,7 +693,7 @@ class OptimizationGoals1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["event"] + kind: Literal["event"] = "event" event_sources: Annotated[ list[EventSource], Field( @@ -2126,6 +2126,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -2331,6 +2337,12 @@ class Assets65(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -2544,6 +2556,12 @@ class Assets66(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -2752,11 +2770,12 @@ class Assets67(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -2784,6 +2803,11 @@ class Assets67(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy61(DeclaredBy): @@ -2914,11 +2938,12 @@ class Assets68(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -2946,6 +2971,11 @@ class Assets68(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy62(DeclaredBy): @@ -3076,6 +3106,12 @@ class Assets69(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -3223,7 +3259,18 @@ class Assets70(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -3389,6 +3436,12 @@ class Assets71(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -3538,6 +3591,12 @@ class Assets72(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -3786,6 +3845,12 @@ class Assets73(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -3948,6 +4013,12 @@ class Assets74(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -4120,11 +4191,12 @@ class Assets75(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -4148,6 +4220,11 @@ class Assets75(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy69(DeclaredBy): @@ -4278,11 +4355,12 @@ class Assets76(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -4306,6 +4384,11 @@ class Assets76(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -4317,6 +4400,12 @@ class Assets77(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -4499,6 +4588,12 @@ class Assets78(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class FeedFieldMapping4(FeedFieldMapping): @@ -4606,6 +4701,12 @@ class Assets79(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class Input(AdCPBaseModel): @@ -4811,7 +4912,9 @@ class Creative(AdCPBaseModel): | Assets78 | Assets79, ], - Field(description="Assets required by the format, keyed by asset_id"), + Field( + description="Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] inputs: Annotated[ list[Input] | None, diff --git a/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_response.py b/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_response.py index eee6156d..0eb425da 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/create_media_buy_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/create_media_buy_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -2273,7 +2273,7 @@ class Target(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[ float, Field(description="Target cost per metric unit in the buy currency", gt=0.0) ] @@ -2283,7 +2283,7 @@ class Target6(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["threshold_rate"] + kind: Literal["threshold_rate"] = "threshold_rate" value: Annotated[ float, Field( @@ -2297,7 +2297,7 @@ class OptimizationGoals(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["metric"] + kind: Literal["metric"] = "metric" metric: Annotated[ Metric3, Field( @@ -2380,7 +2380,7 @@ class Target7(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[float, Field(description="Target cost per event in the buy currency", gt=0.0)] @@ -2388,7 +2388,7 @@ class Target8(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["per_ad_spend"] + kind: Literal["per_ad_spend"] = "per_ad_spend" value: Annotated[ float, Field(description="Target return ratio (e.g., 4.0 means $4 of value per $1 spent)", gt=0.0), @@ -2399,7 +2399,7 @@ class Target9(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["maximize_value"] + kind: Literal["maximize_value"] = "maximize_value" class PostClick(Suppress): @@ -2432,7 +2432,7 @@ class OptimizationGoals3(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["event"] + kind: Literal["event"] = "event" event_sources: Annotated[ list[EventSource], Field( @@ -2817,7 +2817,7 @@ class SignalId(AdCPBaseModel): Field( description="Discriminator indicating this signal is from a data provider's published catalog" ), - ] + ] = "catalog" data_provider_domain: Annotated[ str, Field( @@ -2843,7 +2843,7 @@ class SignalId2(AdCPBaseModel): Field( description="Discriminator indicating this signal is native to the agent (not from a data provider catalog)" ), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field( @@ -2865,12 +2865,14 @@ class AudienceTargeting(AdCPBaseModel): ) type: Annotated[ Literal["signal"], Field(description="Discriminator for signal-based selectors") - ] + ] = "signal" signal_id: Annotated[ SignalId | SignalId2, Field(description="The signal to target", discriminator="source", title="Signal ID"), ] - value_type: Annotated[Literal["binary"], Field(description="Discriminator for binary signals")] + value_type: Annotated[ + Literal["binary"], Field(description="Discriminator for binary signals") + ] = "binary" value: Annotated[ bool, Field( @@ -2885,14 +2887,14 @@ class AudienceTargeting1(AdCPBaseModel): ) type: Annotated[ Literal["signal"], Field(description="Discriminator for signal-based selectors") - ] + ] = "signal" signal_id: Annotated[ SignalId | SignalId2, Field(description="The signal to target", discriminator="source", title="Signal ID"), ] value_type: Annotated[ Literal["categorical"], Field(description="Discriminator for categorical signals") - ] + ] = "categorical" values: Annotated[ list[str], Field( @@ -2908,14 +2910,14 @@ class AudienceTargeting2(AdCPBaseModel): ) type: Annotated[ Literal["signal"], Field(description="Discriminator for signal-based selectors") - ] + ] = "signal" signal_id: Annotated[ SignalId | SignalId2, Field(description="The signal to target", discriminator="source", title="Signal ID"), ] value_type: Annotated[ Literal["numeric"], Field(description="Discriminator for numeric signals") - ] + ] = "numeric" min_value: Annotated[ float | None, Field( @@ -2936,7 +2938,7 @@ class AudienceTargeting3(AdCPBaseModel): ) type: Annotated[ Literal["description"], Field(description="Discriminator for description-based selectors") - ] + ] = "description" description: Annotated[ str, Field( @@ -3327,7 +3329,7 @@ class CreateMediaBuyResponse6(AdCPBaseModel): Field( description="Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose status field carries a MediaBuyStatus value (pending_creatives, pending_start, active). See task-status.json for the full task-status enum." ), - ] + ] = "submitted" task_id: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_request.py b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_request.py index 821a7fd8..500f58f9 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/get_media_buy_delivery_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_response.py b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_response.py index 671126a9..ebaaacf7 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buy_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/get_media_buy_delivery_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_request.py b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_request.py index 2c1f36bd..56c81e23 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/get_media_buys_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_response.py b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_response.py index 8fbffd69..ab62ea81 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/get_media_buys_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/get_media_buys_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/get_products_request.py b/src/adcp/types/generated_poc/bundled/media_buy/get_products_request.py index 03187234..b39f3ef7 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/get_products_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/get_products_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/get_products_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -27,7 +27,7 @@ class Refine(AdCPBaseModel): Field( description="Change scoped to the overall request — direction for the selection as a whole." ), - ] + ] = "request" ask: Annotated[ str, Field( @@ -43,20 +43,22 @@ class Action(Enum): more_like_this = "more_like_this" -class Refine4(AdCPBaseModel): +class Refine6(AdCPBaseModel): model_config = ConfigDict( extra="forbid", ) - scope: Annotated[Literal["product"], Field(description="Change scoped to a specific product.")] - id: Annotated[ + scope: Annotated[ + Literal["product"], Field(description="Change scoped to a specific product.") + ] = "product" + product_id: Annotated[ str, Field(description="Product ID from a previous get_products response.", min_length=1) ] action: Annotated[ - Action, + Action | None, Field( - description="'include': return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned)." + description="'include' (default): return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned). Optional — when omitted, the seller treats the entry as action: 'include'." ), - ] + ] = Action.include ask: Annotated[ str | None, Field( @@ -72,22 +74,22 @@ class Action5(Enum): finalize = "finalize" -class Refine5(AdCPBaseModel): +class Refine7(AdCPBaseModel): model_config = ConfigDict( extra="forbid", ) scope: Annotated[ Literal["proposal"], Field(description="Change scoped to a specific proposal.") - ] - id: Annotated[ + ] = "proposal" + proposal_id: Annotated[ str, Field(description="Proposal ID from a previous get_products response.", min_length=1) ] action: Annotated[ - Action5, + Action5 | None, Field( - description="'include': return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold — transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests — they represent a commitment to wait for the result." + description="'include' (default): return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold — transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests — they represent a commitment to wait for the result. Optional — when omitted, the seller treats the entry as action: 'include'." ), - ] + ] = Action5.include ask: Annotated[ str | None, Field( @@ -97,6 +99,16 @@ class Refine5(AdCPBaseModel): ] = None +class Refine4(RootModel[Refine | Refine6 | Refine7]): + root: Annotated[Refine | Refine6 | Refine7, Field(discriminator="scope")] + + def __getattr__(self, name: str) -> Any: + """Proxy attribute access to the wrapped type.""" + if name.startswith("_"): + raise AttributeError(name) + return getattr(self.root, name) + + class DataSubjectContestation(AdCPBaseModel): model_config = ConfigDict( extra="forbid", @@ -727,7 +739,7 @@ class SignalId(AdCPBaseModel): Field( description="Discriminator indicating this signal is from a data provider's published catalog" ), - ] + ] = "catalog" data_provider_domain: Annotated[ str, Field( @@ -753,7 +765,7 @@ class SignalId9(AdCPBaseModel): Field( description="Discriminator indicating this signal is native to the agent (not from a data provider catalog)" ), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field( @@ -777,7 +789,9 @@ class SignalTargeting1(AdCPBaseModel): SignalId | SignalId9, Field(description="The signal to target", discriminator="source", title="Signal ID"), ] - value_type: Annotated[Literal["binary"], Field(description="Discriminator for binary signals")] + value_type: Annotated[ + Literal["binary"], Field(description="Discriminator for binary signals") + ] = "binary" value: Annotated[ bool, Field( @@ -796,7 +810,7 @@ class SignalTargeting2(AdCPBaseModel): ] value_type: Annotated[ Literal["categorical"], Field(description="Discriminator for categorical signals") - ] + ] = "categorical" values: Annotated[ list[str], Field( @@ -816,7 +830,7 @@ class SignalTargeting3(AdCPBaseModel): ] value_type: Annotated[ Literal["numeric"], Field(description="Discriminator for numeric signals") - ] + ] = "numeric" min_value: Annotated[ float | None, Field( @@ -1407,7 +1421,7 @@ class GetProductsRequest(AdCPBaseModel): ), ] = None refine: Annotated[ - list[Refine | Refine4 | Refine5] | None, + list[Refine4] | None, Field( description="Array of change requests for iterating on products and proposals from a previous get_products response. Each entry declares a scope (request, product, or proposal) and what the buyer is asking for. Only valid when buying_mode is 'refine'. The seller responds to each entry via refinement_applied in the response, matched by position.", min_length=1, diff --git a/src/adcp/types/generated_poc/bundled/media_buy/get_products_response.py b/src/adcp/types/generated_poc/bundled/media_buy/get_products_response.py index c3276f01..c65af0aa 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/get_products_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/get_products_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/get_products_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -27,7 +27,7 @@ class PublisherProperties1(AdCPBaseModel): Field( description="Discriminator indicating all properties from this publisher are included" ), - ] + ] = "all" class PropertyId(RootModel[str]): @@ -56,7 +56,7 @@ class PublisherProperties2(AdCPBaseModel): selection_type: Annotated[ Literal["by_id"], Field(description="Discriminator indicating selection by specific property IDs"), - ] + ] = "by_id" property_ids: Annotated[ list[PropertyId], Field(description="Specific property IDs from the publisher's adagents.json", min_length=1), @@ -88,7 +88,7 @@ class PublisherProperties3(AdCPBaseModel): ] selection_type: Annotated[ Literal["by_tag"], Field(description="Discriminator indicating selection by property tags") - ] + ] = "by_tag" property_tags: Annotated[ list[PropertyTag], Field( @@ -395,7 +395,9 @@ class PricingOptions(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpm"], Field(description="Cost per 1,000 impressions")] + pricing_model: Annotated[Literal["cpm"], Field(description="Cost per 1,000 impressions")] = ( + "cpm" + ) currency: Annotated[ str, Field( @@ -491,7 +493,7 @@ class PricingOptions1(AdCPBaseModel): ] pricing_model: Annotated[ Literal["vcpm"], Field(description="Cost per 1,000 viewable impressions (MRC standard)") - ] + ] = "vcpm" currency: Annotated[ str, Field( @@ -585,7 +587,7 @@ class PricingOptions2(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpc"], Field(description="Cost per click")] + pricing_model: Annotated[Literal["cpc"], Field(description="Cost per click")] = "cpc" currency: Annotated[ str, Field( @@ -681,7 +683,7 @@ class PricingOptions3(AdCPBaseModel): ] pricing_model: Annotated[ Literal["cpcv"], Field(description="Cost per completed view (100% completion)") - ] + ] = "cpcv" currency: Annotated[ str, Field( @@ -800,7 +802,9 @@ class PricingOptions4(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpv"], Field(description="Cost per view at threshold")] + pricing_model: Annotated[Literal["cpv"], Field(description="Cost per view at threshold")] = ( + "cpv" + ) currency: Annotated[ str, Field( @@ -928,7 +932,9 @@ class PricingOptions5(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpp"], Field(description="Cost per Gross Rating Point")] + pricing_model: Annotated[Literal["cpp"], Field(description="Cost per Gross Rating Point")] = ( + "cpp" + ) currency: Annotated[ str, Field( @@ -1025,7 +1031,7 @@ class PricingOptions6(AdCPBaseModel): ] pricing_model: Annotated[ Literal["cpa"], Field(description="Cost per acquisition (conversion event)") - ] + ] = "cpa" event_type: Annotated[ EventType, Field( @@ -1083,7 +1089,7 @@ class Parameters5(AdCPBaseModel): ) type: Annotated[ Literal["dooh"], Field(description="Discriminator identifying this as DOOH parameters") - ] + ] = "dooh" sov_percentage: Annotated[ float | None, Field(description="Guaranteed share of voice as a percentage (0-100)", ge=0.0, le=100.0), @@ -1155,7 +1161,7 @@ class PricingOptions7(AdCPBaseModel): ] pricing_model: Annotated[ Literal["flat_rate"], Field(description="Fixed cost regardless of delivery volume") - ] + ] = "flat_rate" currency: Annotated[ str, Field( @@ -1282,7 +1288,7 @@ class PricingOptions8(AdCPBaseModel): pricing_model: Annotated[ Literal["time"], Field(description="Cost per time unit - rate scales with campaign duration"), - ] + ] = "time" currency: Annotated[ str, Field( @@ -2363,7 +2369,7 @@ class DataProviderSignals1(AdCPBaseModel): Field( description="Discriminator indicating all signals from this data provider are included" ), - ] + ] = "all" class SignalId(RootModel[str]): @@ -2384,7 +2390,7 @@ class DataProviderSignals2(AdCPBaseModel): selection_type: Annotated[ Literal["by_id"], Field(description="Discriminator indicating selection by specific signal IDs"), - ] + ] = "by_id" signal_ids: Annotated[ list[SignalId], Field(description="Specific signal IDs from the data provider's catalog", min_length=1), @@ -2408,7 +2414,7 @@ class DataProviderSignals3(AdCPBaseModel): ] selection_type: Annotated[ Literal["by_tag"], Field(description="Discriminator indicating selection by signal tags") - ] + ] = "by_tag" signal_tags: Annotated[ list[SignalTag], Field( @@ -2732,7 +2738,7 @@ class Collection(AdCPBaseModel): ] -class Status17(Enum): +class Status19(Enum): scheduled = "scheduled" tentative = "tentative" live = "live" @@ -2956,7 +2962,7 @@ class Installment(AdCPBaseModel): AwareDatetime | None, Field(description="When the installment airs or publishes (ISO 8601)") ] = None status: Annotated[ - Status17 | None, + Status19 | None, Field(description="Lifecycle status of the installment", title="Installment Status"), ] = None duration_seconds: Annotated[ @@ -4419,36 +4425,72 @@ class Error(AdCPBaseModel): ] = None -class Scope(Enum): - request = "request" - product = "product" - proposal = "proposal" - - -class Status18(Enum): +class Status20(Enum): applied = "applied" partial = "partial" unable = "unable" -class RefinementAppliedItem(AdCPBaseModel): +class RefinementApplied(AdCPBaseModel): model_config = ConfigDict( extra="forbid", ) scope: Annotated[ - Scope | None, + Literal["request"], + Field(description="Echoes scope 'request' from the corresponding refine entry."), + ] = "request" + status: Annotated[ + Status20, Field( - description="Echoes the scope from the corresponding refine entry. Allows orchestrators to cross-validate alignment." + description="'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled — see notes for details. 'unable': the seller could not fulfill the ask — see notes for why." + ), + ] + notes: Annotated[ + str | None, + Field( + description="Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." ), ] = None - id: Annotated[ + + +class RefinementApplied6(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + scope: Annotated[ + Literal["product"], + Field(description="Echoes scope 'product' from the corresponding refine entry."), + ] = "product" + product_id: Annotated[ + str, Field(description="Echoes product_id from the corresponding refine entry.") + ] + status: Annotated[ + Status20, + Field( + description="'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled — see notes for details. 'unable': the seller could not fulfill the ask — see notes for why." + ), + ] + notes: Annotated[ str | None, Field( - description="Echoes the id from the corresponding refine entry (for product and proposal scopes)." + description="Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." ), ] = None + + +class RefinementApplied7(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + scope: Annotated[ + Literal["proposal"], + Field(description="Echoes scope 'proposal' from the corresponding refine entry."), + ] = "proposal" + proposal_id: Annotated[ + str, Field(description="Echoes proposal_id from the corresponding refine entry.") + ] status: Annotated[ - Status18, + Status20, Field( description="'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled — see notes for details. 'unable': the seller could not fulfill the ask — see notes for why." ), @@ -4461,7 +4503,19 @@ class RefinementAppliedItem(AdCPBaseModel): ] = None -class Scope5(Enum): +class RefinementApplied4(RootModel[RefinementApplied | RefinementApplied6 | RefinementApplied7]): + root: Annotated[ + RefinementApplied | RefinementApplied6 | RefinementApplied7, Field(discriminator="scope") + ] + + def __getattr__(self, name: str) -> Any: + """Proxy attribute access to the wrapped type.""" + if name.startswith("_"): + raise AttributeError(name) + return getattr(self.root, name) + + +class Scope(Enum): products = "products" pricing = "pricing" forecast = "forecast" @@ -4477,7 +4531,7 @@ class IncompleteItem(AdCPBaseModel): extra="forbid", ) scope: Annotated[ - Scope5, + Scope, Field( description="'products': not all inventory sources were searched. 'pricing': products returned but pricing is absent or unconfirmed. 'forecast': products returned but forecast data is absent. 'proposals': proposals were not generated or are incomplete." ), @@ -4543,9 +4597,9 @@ class GetProductsResponse(AdCPBaseModel): ), ] = None refinement_applied: Annotated[ - list[RefinementAppliedItem] | None, + list[RefinementApplied4] | None, Field( - description="Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'." + description="Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'. Each entry MUST echo the request entry's scope and — for product and proposal scopes — the matching id field (product_id or proposal_id), so orchestrators can cross-validate alignment." ), ] = None incomplete: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_request.py b/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_request.py index 1690461a..b9a57ddd 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/list_creative_formats_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_response.py b/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_response.py index 72e843e4..00f6854a 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/list_creative_formats_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/list_creative_formats_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -1260,7 +1260,7 @@ class PricingOption161(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -1276,7 +1276,7 @@ class PricingOption162(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -1311,7 +1311,7 @@ class PricingOption163(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -1328,7 +1328,7 @@ class PricingOption164(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -1363,7 +1363,7 @@ class PricingOption165(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( @@ -1542,7 +1542,7 @@ class ScalarBinding(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["scalar"] + kind: Literal["scalar"] = "scalar" asset_id: Annotated[ str, Field( @@ -1568,7 +1568,7 @@ class AssetPoolBinding(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["asset_pool"] + kind: Literal["asset_pool"] = "asset_pool" asset_id: Annotated[ str, Field( @@ -1725,7 +1725,7 @@ class BaseIndividualAsset(AdCPBaseModel): item_type: Annotated[ Literal["individual"], Field(description="Discriminator indicating this is an individual asset"), - ] + ] = "individual" asset_id: Annotated[ str, Field( @@ -1901,7 +1901,7 @@ class FieldBindings(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["catalog_group"] + kind: Literal["catalog_group"] = "catalog_group" format_group_id: Annotated[ str, Field(description="The asset_group_id of a repeatable_group in the format's assets array."), @@ -2130,7 +2130,7 @@ class Assets173(AdCPBaseModel): item_type: Annotated[ Literal["repeatable_group"], Field(description="Discriminator indicating this is a repeatable asset group"), - ] + ] = "repeatable_group" asset_group_id: Annotated[ str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')") ] diff --git a/src/adcp/types/generated_poc/bundled/media_buy/log_event_request.py b/src/adcp/types/generated_poc/bundled/media_buy/log_event_request.py index b33d0183..8ac82ff2 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/log_event_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/log_event_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/log_event_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/log_event_response.py b/src/adcp/types/generated_poc/bundled/media_buy/log_event_response.py index 339a3b4d..238158d2 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/log_event_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/log_event_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/log_event_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/package_request.py b/src/adcp/types/generated_poc/bundled/media_buy/package_request.py index 401344ad..e5526ec3 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/package_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/package_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/package_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -431,7 +431,7 @@ class Target(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[ float, Field(description="Target cost per metric unit in the buy currency", gt=0.0) ] @@ -441,7 +441,7 @@ class Target16(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["threshold_rate"] + kind: Literal["threshold_rate"] = "threshold_rate" value: Annotated[ float, Field( @@ -455,7 +455,7 @@ class OptimizationGoals(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["metric"] + kind: Literal["metric"] = "metric" metric: Annotated[ Metric, Field( @@ -538,7 +538,7 @@ class Target17(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[float, Field(description="Target cost per event in the buy currency", gt=0.0)] @@ -546,7 +546,7 @@ class Target18(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["per_ad_spend"] + kind: Literal["per_ad_spend"] = "per_ad_spend" value: Annotated[ float, Field(description="Target return ratio (e.g., 4.0 means $4 of value per $1 spent)", gt=0.0), @@ -557,7 +557,7 @@ class Target19(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["maximize_value"] + kind: Literal["maximize_value"] = "maximize_value" class PostClick(Window): @@ -590,7 +590,7 @@ class OptimizationGoals5(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["event"] + kind: Literal["event"] = "event" event_sources: Annotated[ list[EventSource], Field( @@ -2033,6 +2033,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -2238,6 +2244,12 @@ class Assets230(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -2451,6 +2463,12 @@ class Assets231(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -2659,11 +2677,12 @@ class Assets232(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -2691,6 +2710,11 @@ class Assets232(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy141(DeclaredBy): @@ -2821,11 +2845,12 @@ class Assets233(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -2853,6 +2878,11 @@ class Assets233(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy142(DeclaredBy): @@ -2983,6 +3013,12 @@ class Assets234(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -3130,7 +3166,18 @@ class Assets235(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -3296,6 +3343,12 @@ class Assets236(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -3445,6 +3498,12 @@ class Assets237(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -3693,6 +3752,12 @@ class Assets238(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -3855,6 +3920,12 @@ class Assets239(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -4027,11 +4098,12 @@ class Assets240(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -4055,6 +4127,11 @@ class Assets240(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy149(DeclaredBy): @@ -4185,11 +4262,12 @@ class Assets241(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -4213,6 +4291,11 @@ class Assets241(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -4224,6 +4307,12 @@ class Assets242(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -4406,6 +4495,12 @@ class Assets243(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class FeedFieldMapping11(FeedFieldMapping): @@ -4513,6 +4608,12 @@ class Assets244(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class Input(AdCPBaseModel): @@ -4718,7 +4819,9 @@ class Creative(AdCPBaseModel): | Assets243 | Assets244, ], - Field(description="Assets required by the format, keyed by asset_id"), + Field( + description="Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] inputs: Annotated[ list[Input] | None, diff --git a/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_request.py b/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_request.py index 0a981ba4..1c6f3238 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/provide_performance_feedback_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_response.py b/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_response.py index c2d479a7..d34e5e97 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/provide_performance_feedback_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/provide_performance_feedback_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_request.py b/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_request.py index 68b8e6b1..0de780b7 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/sync_audiences_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_response.py b/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_response.py index 0223389f..46076997 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/sync_audiences_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/sync_audiences_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_request.py b/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_request.py index b911871f..4f76a296 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/sync_catalogs_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_response.py b/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_response.py index 0bc7ed8f..536f58a6 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/sync_catalogs_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/sync_catalogs_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_request.py b/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_request.py index e093bce1..10b5416f 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/sync_event_sources_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_response.py b/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_response.py index 6cba2b75..a49ebe99 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/sync_event_sources_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/sync_event_sources_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_request.py b/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_request.py index f1ab4e84..f41a8df4 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_request.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/update_media_buy_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -486,7 +486,7 @@ class Target(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[ float, Field(description="Target cost per metric unit in the buy currency", gt=0.0) ] @@ -496,7 +496,7 @@ class Target21(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["threshold_rate"] + kind: Literal["threshold_rate"] = "threshold_rate" value: Annotated[ float, Field( @@ -510,7 +510,7 @@ class OptimizationGoals(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["metric"] + kind: Literal["metric"] = "metric" metric: Annotated[ Metric, Field( @@ -593,7 +593,7 @@ class Target22(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[float, Field(description="Target cost per event in the buy currency", gt=0.0)] @@ -601,7 +601,7 @@ class Target23(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["per_ad_spend"] + kind: Literal["per_ad_spend"] = "per_ad_spend" value: Annotated[ float, Field(description="Target return ratio (e.g., 4.0 means $4 of value per $1 spent)", gt=0.0), @@ -612,7 +612,7 @@ class Target24(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["maximize_value"] + kind: Literal["maximize_value"] = "maximize_value" class PostClick(Window): @@ -645,7 +645,7 @@ class OptimizationGoals7(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["event"] + kind: Literal["event"] = "event" event_sources: Annotated[ list[EventSource], Field( @@ -1937,6 +1937,12 @@ class Assets(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -2142,6 +2148,12 @@ class Assets318(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -2355,6 +2367,12 @@ class Assets319(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -2563,11 +2581,12 @@ class Assets320(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -2595,6 +2614,11 @@ class Assets320(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy222(DeclaredBy): @@ -2725,11 +2749,12 @@ class Assets321(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -2757,6 +2782,11 @@ class Assets321(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy223(DeclaredBy): @@ -2887,6 +2917,12 @@ class Assets322(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -3034,7 +3070,18 @@ class Assets323(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -3200,6 +3247,12 @@ class Assets324(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -3349,6 +3402,12 @@ class Assets325(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -3597,6 +3656,12 @@ class Assets326(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -3759,6 +3824,12 @@ class Assets327(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -3931,11 +4002,12 @@ class Assets328(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -3959,6 +4031,11 @@ class Assets328(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy230(DeclaredBy): @@ -4089,11 +4166,12 @@ class Assets329(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -4117,6 +4195,11 @@ class Assets329(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class MarkdownFlavor(Enum): @@ -4128,6 +4211,12 @@ class Assets330(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( @@ -4310,6 +4399,12 @@ class Assets331(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class FeedFieldMapping18(FeedFieldMapping): @@ -4417,6 +4512,12 @@ class Assets332(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class Input(AdCPBaseModel): @@ -4622,7 +4723,9 @@ class Creative(AdCPBaseModel): | Assets331 | Assets332, ], - Field(description="Assets required by the format, keyed by asset_id"), + Field( + description="Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] inputs: Annotated[ list[Input] | None, @@ -5103,7 +5206,7 @@ class OptimizationGoals8(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["metric"] + kind: Literal["metric"] = "metric" metric: Annotated[ Metric, Field( @@ -5190,7 +5293,7 @@ class OptimizationGoals9(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["event"] + kind: Literal["event"] = "event" event_sources: Annotated[ list[EventSource9], Field( @@ -6136,6 +6239,12 @@ class Assets333(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -6280,6 +6389,12 @@ class Assets334(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] @@ -6493,6 +6608,12 @@ class Assets335(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) @@ -6658,11 +6779,12 @@ class Assets336(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -6690,6 +6812,11 @@ class Assets336(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class DeclaredBy236(DeclaredBy): @@ -6820,11 +6947,12 @@ class Assets337(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ VastVersion | None, Field(description="VAST specification version", title="VAST Version") ] = None @@ -6852,6 +6980,11 @@ class Assets337(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class DeclaredBy237(DeclaredBy): @@ -6982,6 +7115,12 @@ class Assets338(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None @@ -7123,7 +7262,18 @@ class Assets339(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ UrlType | None, Field( @@ -7271,6 +7421,12 @@ class Assets340(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ @@ -7414,6 +7570,12 @@ class Assets341(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ ModuleType | None, @@ -7564,6 +7726,12 @@ class Assets342(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[Method | None, Field(description="HTTP method", title="HTTP Method")] = ( Method.POST @@ -7726,6 +7894,12 @@ class Assets343(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") @@ -7867,11 +8041,12 @@ class Assets344(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -7895,6 +8070,11 @@ class Assets344(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DeclaredBy244(DeclaredBy): @@ -8025,11 +8205,12 @@ class Assets345(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ DaastVersion | None, Field(description="DAAST specification version", title="DAAST Version") ] = None @@ -8053,6 +8234,11 @@ class Assets345(AdCPBaseModel): title="Provenance", ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class Assets346(Assets330): @@ -8170,6 +8356,12 @@ class Assets347(AdCPBaseModel): description="Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json." ), ] = None + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" class FeedFieldMapping20(FeedFieldMapping): @@ -8277,6 +8469,12 @@ class Assets348(AdCPBaseModel): min_length=1, ), ] = None + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" class IndustryIdentifier12(IndustryIdentifier): @@ -8440,7 +8638,9 @@ class Creative12(AdCPBaseModel): | Assets347 | Assets348, ], - Field(description="Assets required by the format, keyed by asset_id"), + Field( + description="Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] inputs: Annotated[ list[Input] | None, diff --git a/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_response.py b/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_response.py index 5471aec7..037c7e40 100644 --- a/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_response.py +++ b/src/adcp/types/generated_poc/bundled/media_buy/update_media_buy_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/media_buy/update_media_buy_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -1852,7 +1852,7 @@ class Target(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[ float, Field(description="Target cost per metric unit in the buy currency", gt=0.0) ] @@ -1862,7 +1862,7 @@ class Target31(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["threshold_rate"] + kind: Literal["threshold_rate"] = "threshold_rate" value: Annotated[ float, Field( @@ -1876,7 +1876,7 @@ class OptimizationGoals(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["metric"] + kind: Literal["metric"] = "metric" metric: Annotated[ Metric13, Field( @@ -1959,7 +1959,7 @@ class Target32(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[float, Field(description="Target cost per event in the buy currency", gt=0.0)] @@ -1967,7 +1967,7 @@ class Target33(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["per_ad_spend"] + kind: Literal["per_ad_spend"] = "per_ad_spend" value: Annotated[ float, Field(description="Target return ratio (e.g., 4.0 means $4 of value per $1 spent)", gt=0.0), @@ -1978,7 +1978,7 @@ class Target34(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["maximize_value"] + kind: Literal["maximize_value"] = "maximize_value" class PostClick(Suppress): @@ -2011,7 +2011,7 @@ class OptimizationGoals11(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["event"] + kind: Literal["event"] = "event" event_sources: Annotated[ list[EventSource], Field( diff --git a/src/adcp/types/generated_poc/bundled/property/create_property_list_request.py b/src/adcp/types/generated_poc/bundled/property/create_property_list_request.py index 51178ecf..01c4e536 100644 --- a/src/adcp/types/generated_poc/bundled/property/create_property_list_request.py +++ b/src/adcp/types/generated_poc/bundled/property/create_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/create_property_list_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -125,7 +125,7 @@ class BaseProperties1(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_tags"], Field(description="Discriminator indicating selection by property tags within a publisher"), - ] + ] = "publisher_tags" publisher_domain: Annotated[ str, Field( @@ -163,7 +163,7 @@ class BaseProperties2(AdCPBaseModel): Field( description="Discriminator indicating selection by specific property IDs within a publisher" ), - ] + ] = "publisher_ids" publisher_domain: Annotated[ str, Field( @@ -235,7 +235,7 @@ class BaseProperties3(AdCPBaseModel): selection_type: Annotated[ Literal["identifiers"], Field(description="Discriminator indicating selection by direct identifiers"), - ] + ] = "identifiers" identifiers: Annotated[ list[Identifier], Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), diff --git a/src/adcp/types/generated_poc/bundled/property/create_property_list_response.py b/src/adcp/types/generated_poc/bundled/property/create_property_list_response.py index b7f076ba..00cb2cf5 100644 --- a/src/adcp/types/generated_poc/bundled/property/create_property_list_response.py +++ b/src/adcp/types/generated_poc/bundled/property/create_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/create_property_list_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -125,7 +125,7 @@ class BaseProperties(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_tags"], Field(description="Discriminator indicating selection by property tags within a publisher"), - ] + ] = "publisher_tags" publisher_domain: Annotated[ str, Field( @@ -163,7 +163,7 @@ class BaseProperties6(AdCPBaseModel): Field( description="Discriminator indicating selection by specific property IDs within a publisher" ), - ] + ] = "publisher_ids" publisher_domain: Annotated[ str, Field( @@ -235,7 +235,7 @@ class BaseProperties7(AdCPBaseModel): selection_type: Annotated[ Literal["identifiers"], Field(description="Discriminator indicating selection by direct identifiers"), - ] + ] = "identifiers" identifiers: Annotated[ list[Identifier], Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), @@ -423,7 +423,7 @@ class PricingOption1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -439,7 +439,7 @@ class PricingOption2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -474,7 +474,7 @@ class PricingOption3(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -491,7 +491,7 @@ class PricingOption4(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -526,7 +526,7 @@ class PricingOption5(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/bundled/property/delete_property_list_request.py b/src/adcp/types/generated_poc/bundled/property/delete_property_list_request.py index 0344378b..d14794a2 100644 --- a/src/adcp/types/generated_poc/bundled/property/delete_property_list_request.py +++ b/src/adcp/types/generated_poc/bundled/property/delete_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/delete_property_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/property/delete_property_list_response.py b/src/adcp/types/generated_poc/bundled/property/delete_property_list_response.py index f2dcbb88..d49da111 100644 --- a/src/adcp/types/generated_poc/bundled/property/delete_property_list_response.py +++ b/src/adcp/types/generated_poc/bundled/property/delete_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/delete_property_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/property/get_property_list_request.py b/src/adcp/types/generated_poc/bundled/property/get_property_list_request.py index d014e885..099a8aee 100644 --- a/src/adcp/types/generated_poc/bundled/property/get_property_list_request.py +++ b/src/adcp/types/generated_poc/bundled/property/get_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/get_property_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/property/get_property_list_response.py b/src/adcp/types/generated_poc/bundled/property/get_property_list_response.py index d53d544b..5ec4d741 100644 --- a/src/adcp/types/generated_poc/bundled/property/get_property_list_response.py +++ b/src/adcp/types/generated_poc/bundled/property/get_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/get_property_list_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -125,7 +125,7 @@ class BaseProperties(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_tags"], Field(description="Discriminator indicating selection by property tags within a publisher"), - ] + ] = "publisher_tags" publisher_domain: Annotated[ str, Field( @@ -163,7 +163,7 @@ class BaseProperties10(AdCPBaseModel): Field( description="Discriminator indicating selection by specific property IDs within a publisher" ), - ] + ] = "publisher_ids" publisher_domain: Annotated[ str, Field( @@ -235,7 +235,7 @@ class BaseProperties11(AdCPBaseModel): selection_type: Annotated[ Literal["identifiers"], Field(description="Discriminator indicating selection by direct identifiers"), - ] + ] = "identifiers" identifiers: Annotated[ list[Identifier], Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), @@ -423,7 +423,7 @@ class PricingOption131(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -439,7 +439,7 @@ class PricingOption132(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -474,7 +474,7 @@ class PricingOption133(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -491,7 +491,7 @@ class PricingOption134(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -526,7 +526,7 @@ class PricingOption135(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/bundled/property/list_property_lists_request.py b/src/adcp/types/generated_poc/bundled/property/list_property_lists_request.py index e21a8373..6dc13d7b 100644 --- a/src/adcp/types/generated_poc/bundled/property/list_property_lists_request.py +++ b/src/adcp/types/generated_poc/bundled/property/list_property_lists_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/list_property_lists_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/property/list_property_lists_response.py b/src/adcp/types/generated_poc/bundled/property/list_property_lists_response.py index 861cd749..615bda73 100644 --- a/src/adcp/types/generated_poc/bundled/property/list_property_lists_response.py +++ b/src/adcp/types/generated_poc/bundled/property/list_property_lists_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/list_property_lists_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -125,7 +125,7 @@ class BaseProperties(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_tags"], Field(description="Discriminator indicating selection by property tags within a publisher"), - ] + ] = "publisher_tags" publisher_domain: Annotated[ str, Field( @@ -163,7 +163,7 @@ class BaseProperties14(AdCPBaseModel): Field( description="Discriminator indicating selection by specific property IDs within a publisher" ), - ] + ] = "publisher_ids" publisher_domain: Annotated[ str, Field( @@ -235,7 +235,7 @@ class BaseProperties15(AdCPBaseModel): selection_type: Annotated[ Literal["identifiers"], Field(description="Discriminator indicating selection by direct identifiers"), - ] + ] = "identifiers" identifiers: Annotated[ list[Identifier], Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), @@ -423,7 +423,7 @@ class PricingOption191(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -439,7 +439,7 @@ class PricingOption192(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -474,7 +474,7 @@ class PricingOption193(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -491,7 +491,7 @@ class PricingOption194(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -526,7 +526,7 @@ class PricingOption195(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/bundled/property/update_property_list_request.py b/src/adcp/types/generated_poc/bundled/property/update_property_list_request.py index 36854ac4..5ff21ad6 100644 --- a/src/adcp/types/generated_poc/bundled/property/update_property_list_request.py +++ b/src/adcp/types/generated_poc/bundled/property/update_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/update_property_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -125,7 +125,7 @@ class BaseProperties(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_tags"], Field(description="Discriminator indicating selection by property tags within a publisher"), - ] + ] = "publisher_tags" publisher_domain: Annotated[ str, Field( @@ -163,7 +163,7 @@ class BaseProperties18(AdCPBaseModel): Field( description="Discriminator indicating selection by specific property IDs within a publisher" ), - ] + ] = "publisher_ids" publisher_domain: Annotated[ str, Field( @@ -235,7 +235,7 @@ class BaseProperties19(AdCPBaseModel): selection_type: Annotated[ Literal["identifiers"], Field(description="Discriminator indicating selection by direct identifiers"), - ] + ] = "identifiers" identifiers: Annotated[ list[Identifier], Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), diff --git a/src/adcp/types/generated_poc/bundled/property/update_property_list_response.py b/src/adcp/types/generated_poc/bundled/property/update_property_list_response.py index 75aedf99..f8ca86f0 100644 --- a/src/adcp/types/generated_poc/bundled/property/update_property_list_response.py +++ b/src/adcp/types/generated_poc/bundled/property/update_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/update_property_list_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -125,7 +125,7 @@ class BaseProperties(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_tags"], Field(description="Discriminator indicating selection by property tags within a publisher"), - ] + ] = "publisher_tags" publisher_domain: Annotated[ str, Field( @@ -163,7 +163,7 @@ class BaseProperties22(AdCPBaseModel): Field( description="Discriminator indicating selection by specific property IDs within a publisher" ), - ] + ] = "publisher_ids" publisher_domain: Annotated[ str, Field( @@ -235,7 +235,7 @@ class BaseProperties23(AdCPBaseModel): selection_type: Annotated[ Literal["identifiers"], Field(description="Discriminator indicating selection by direct identifiers"), - ] + ] = "identifiers" identifiers: Annotated[ list[Identifier], Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), @@ -423,7 +423,7 @@ class PricingOption201(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -439,7 +439,7 @@ class PricingOption202(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -474,7 +474,7 @@ class PricingOption203(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -491,7 +491,7 @@ class PricingOption204(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -526,7 +526,7 @@ class PricingOption205(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_request.py b/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_request.py index 0434893b..2f37886d 100644 --- a/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_request.py +++ b/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/validate_property_delivery_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_response.py b/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_response.py index f01aa6f0..4e29aecb 100644 --- a/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_response.py +++ b/src/adcp/types/generated_poc/bundled/property/validate_property_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/property/validate_property_delivery_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -152,7 +152,7 @@ class Status(Enum): unidentified = "unidentified" -class Status49(Enum): +class Status53(Enum): passed = "passed" failed = "failed" warning = "warning" @@ -180,7 +180,7 @@ class Feature(AdCPBaseModel): description="Which feature was evaluated. Data features come from the governance agent's feature catalog (e.g., 'mfa_score', 'carbon_score'). Record-level structural checks use reserved namespaces: 'record:list_membership', 'record:excluded', 'delivery:seller_authorization', 'delivery:click_url_presence'. Reserved prefixes: 'record:', 'delivery:'." ), ] - status: Status49 + status: Status53 policy_id: Annotated[ str | None, Field( @@ -206,7 +206,7 @@ class Feature(AdCPBaseModel): ] = None -class Status50(Enum): +class Status54(Enum): authorized = "authorized" unauthorized = "unauthorized" unknown = "unknown" @@ -225,7 +225,7 @@ class Authorization(AdCPBaseModel): extra="forbid", ) status: Annotated[ - Status50, + Status54, Field( description="Authorization status: authorized (agent in adagents.json), unauthorized (agent not in adagents.json), unknown (could not fetch or parse adagents.json)" ), diff --git a/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_request.py b/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_request.py index 7cd8f2b6..f5c2e472 100644 --- a/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_request.py +++ b/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/protocol/get_adcp_capabilities_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_response.py b/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_response.py index 13f11506..05169d62 100644 --- a/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_response.py +++ b/src/adcp/types/generated_poc/bundled/protocol/get_adcp_capabilities_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/protocol/get_adcp_capabilities_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/signals/activate_signal_request.py b/src/adcp/types/generated_poc/bundled/signals/activate_signal_request.py index c1ca483a..eeb53787 100644 --- a/src/adcp/types/generated_poc/bundled/signals/activate_signal_request.py +++ b/src/adcp/types/generated_poc/bundled/signals/activate_signal_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/signals/activate_signal_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -23,7 +23,7 @@ class Destinations(AdCPBaseModel): type: Annotated[ Literal["platform"], Field(description="Discriminator indicating this is a platform-based deployment"), - ] + ] = "platform" platform: Annotated[ str, Field(description="Platform identifier for DSPs (e.g., 'the-trade-desk', 'amazon-dsp')"), @@ -40,7 +40,7 @@ class Destinations1(AdCPBaseModel): type: Annotated[ Literal["agent"], Field(description="Discriminator indicating this is an agent URL-based deployment"), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field(description="URL identifying the deployment agent (for sales agents, etc.)") ] diff --git a/src/adcp/types/generated_poc/bundled/signals/activate_signal_response.py b/src/adcp/types/generated_poc/bundled/signals/activate_signal_response.py index a780da99..87ad2df2 100644 --- a/src/adcp/types/generated_poc/bundled/signals/activate_signal_response.py +++ b/src/adcp/types/generated_poc/bundled/signals/activate_signal_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/signals/activate_signal_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -15,7 +15,9 @@ class ActivationKey(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - type: Annotated[Literal["segment_id"], Field(description="Segment ID based targeting")] + type: Annotated[Literal["segment_id"], Field(description="Segment ID based targeting")] = ( + "segment_id" + ) segment_id: Annotated[ str, Field(description="The platform-specific segment identifier to use in campaign targeting"), @@ -26,7 +28,9 @@ class ActivationKey1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - type: Annotated[Literal["key_value"], Field(description="Key-value pair based targeting")] + type: Annotated[Literal["key_value"], Field(description="Key-value pair based targeting")] = ( + "key_value" + ) key: Annotated[str, Field(description="The targeting parameter key")] value: Annotated[str, Field(description="The targeting parameter value")] @@ -38,7 +42,7 @@ class Deployments(AdCPBaseModel): type: Annotated[ Literal["platform"], Field(description="Discriminator indicating this is a platform-based deployment"), - ] + ] = "platform" platform: Annotated[str, Field(description="Platform identifier for DSPs")] account: Annotated[str | None, Field(description="Account identifier if applicable")] = None is_live: Annotated[ @@ -79,7 +83,7 @@ class Deployments1(AdCPBaseModel): type: Annotated[ Literal["agent"], Field(description="Discriminator indicating this is an agent URL-based deployment"), - ] + ] = "agent" agent_url: Annotated[AnyUrl, Field(description="URL identifying the deployment agent")] account: Annotated[str | None, Field(description="Account identifier if applicable")] = None is_live: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/signals/get_signals_request.py b/src/adcp/types/generated_poc/bundled/signals/get_signals_request.py index 0ee5187d..944d6271 100644 --- a/src/adcp/types/generated_poc/bundled/signals/get_signals_request.py +++ b/src/adcp/types/generated_poc/bundled/signals/get_signals_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/signals/get_signals_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -115,7 +115,7 @@ class SignalIds1(AdCPBaseModel): Field( description="Discriminator indicating this signal is from a data provider's published catalog" ), - ] + ] = "catalog" data_provider_domain: Annotated[ str, Field( @@ -141,7 +141,7 @@ class SignalIds2(AdCPBaseModel): Field( description="Discriminator indicating this signal is native to the agent (not from a data provider catalog)" ), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field( @@ -181,7 +181,7 @@ class Destinations(AdCPBaseModel): type: Annotated[ Literal["platform"], Field(description="Discriminator indicating this is a platform-based deployment"), - ] + ] = "platform" platform: Annotated[ str, Field(description="Platform identifier for DSPs (e.g., 'the-trade-desk', 'amazon-dsp')"), @@ -198,7 +198,7 @@ class Destinations3(AdCPBaseModel): type: Annotated[ Literal["agent"], Field(description="Discriminator indicating this is an agent URL-based deployment"), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field(description="URL identifying the deployment agent (for sales agents, etc.)") ] diff --git a/src/adcp/types/generated_poc/bundled/signals/get_signals_response.py b/src/adcp/types/generated_poc/bundled/signals/get_signals_response.py index 09cb9a4b..7592506a 100644 --- a/src/adcp/types/generated_poc/bundled/signals/get_signals_response.py +++ b/src/adcp/types/generated_poc/bundled/signals/get_signals_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/signals/get_signals_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -20,7 +20,7 @@ class SignalId(AdCPBaseModel): Field( description="Discriminator indicating this signal is from a data provider's published catalog" ), - ] + ] = "catalog" data_provider_domain: Annotated[ str, Field( @@ -46,7 +46,7 @@ class SignalId16(AdCPBaseModel): Field( description="Discriminator indicating this signal is native to the agent (not from a data provider catalog)" ), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field( @@ -86,7 +86,9 @@ class ActivationKey(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - type: Annotated[Literal["segment_id"], Field(description="Segment ID based targeting")] + type: Annotated[Literal["segment_id"], Field(description="Segment ID based targeting")] = ( + "segment_id" + ) segment_id: Annotated[ str, Field(description="The platform-specific segment identifier to use in campaign targeting"), @@ -97,7 +99,9 @@ class ActivationKey7(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - type: Annotated[Literal["key_value"], Field(description="Key-value pair based targeting")] + type: Annotated[Literal["key_value"], Field(description="Key-value pair based targeting")] = ( + "key_value" + ) key: Annotated[str, Field(description="The targeting parameter key")] value: Annotated[str, Field(description="The targeting parameter value")] @@ -109,7 +113,7 @@ class Deployments(AdCPBaseModel): type: Annotated[ Literal["platform"], Field(description="Discriminator indicating this is a platform-based deployment"), - ] + ] = "platform" platform: Annotated[str, Field(description="Platform identifier for DSPs")] account: Annotated[str | None, Field(description="Account identifier if applicable")] = None is_live: Annotated[ @@ -150,7 +154,7 @@ class Deployments3(AdCPBaseModel): type: Annotated[ Literal["agent"], Field(description="Discriminator indicating this is an agent URL-based deployment"), - ] + ] = "agent" agent_url: Annotated[AnyUrl, Field(description="URL identifying the deployment agent")] account: Annotated[str | None, Field(description="Account identifier if applicable")] = None is_live: Annotated[ @@ -180,7 +184,7 @@ class PricingOption141(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: Annotated[ @@ -196,7 +200,7 @@ class PricingOption142(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -231,7 +235,7 @@ class PricingOption143(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -248,7 +252,7 @@ class PricingOption144(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -283,7 +287,7 @@ class PricingOption145(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_request.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_request.py index ba10234b..1a540b0b 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_request.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_get_offering_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -25,10 +25,17 @@ class SiGetOfferingRequest(AdCPBaseModel): offering_id: Annotated[ str, Field(description="Offering identifier from the catalog to get details for") ] - context: Annotated[ + intent: Annotated[ str | None, Field( - description="Optional natural language context about user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." + description="Optional natural language description of user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." + ), + ] = None + context: Annotated[ + dict[str, Any] | None, + Field( + description="Opaque correlation data that is echoed unchanged in responses. Used for internal tracking, UI session IDs, trace IDs, and other caller-specific identifiers that don't affect protocol behavior. Context data is never parsed by AdCP agents - it's simply preserved and returned.", + title="Context Object", ), ] = None include_products: Annotated[ diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_response.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_response.py index e7ceeab7..cc9f7432 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_response.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_get_offering_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_get_offering_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_request.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_request.py index 190dcfae..103cc640 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_request.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_initiate_session_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -196,9 +196,19 @@ class SiInitiateSessionRequest(AdCPBaseModel): le=99, ), ] = None - context: Annotated[ - str, Field(description="Conversation handoff from the host describing what the user needs") + intent: Annotated[ + str, + Field( + description="Natural language description of user intent — the conversation handoff from the host describing what the user needs from the brand agent" + ), ] + context: Annotated[ + dict[str, Any] | None, + Field( + description="Opaque correlation data that is echoed unchanged in responses. Used for internal tracking, UI session IDs, trace IDs, and other caller-specific identifiers that don't affect protocol behavior. Context data is never parsed by AdCP agents - it's simply preserved and returned.", + title="Context Object", + ), + ] = None identity: Annotated[ Identity, Field( diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_response.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_response.py index b14a6a3c..8e384ceb 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_response.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_initiate_session_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_initiate_session_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_request.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_request.py index d02b6a84..b608c90f 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_request.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_send_message_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_response.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_response.py index c6bd8157..b9395aa3 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_response.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_send_message_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_send_message_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_request.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_request.py index 8ac5a12d..ffb52a0e 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_request.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_terminate_session_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_response.py b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_response.py index 252e0ec9..8b4616ef 100644 --- a/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_response.py +++ b/src/adcp/types/generated_poc/bundled/sponsored_intelligence/si_terminate_session_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: bundled/sponsored_intelligence/si_terminate_session_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/base_collection_source.py b/src/adcp/types/generated_poc/collection/base_collection_source.py index c547d7c5..25c8b298 100644 --- a/src/adcp/types/generated_poc/collection/base_collection_source.py +++ b/src/adcp/types/generated_poc/collection/base_collection_source.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/base_collection_source.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -22,7 +22,7 @@ class BaseCollectionSource2(AdCPBaseModel): Field( description="Discriminator indicating selection by specific collection IDs within a publisher" ), - ] + ] = "publisher_collections" publisher_domain: Annotated[ str, Field( @@ -58,7 +58,7 @@ class BaseCollectionSource1(AdCPBaseModel): Field( description="Discriminator indicating selection by platform-independent distribution identifiers" ), - ] + ] = "distribution_ids" identifiers: Annotated[ list[Identifier], Field( @@ -75,7 +75,7 @@ class BaseCollectionSource3(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_genres"], Field(description="Discriminator indicating selection by genre within a publisher"), - ] + ] = "publisher_genres" publisher_domain: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/collection/collection_list.py b/src/adcp/types/generated_poc/collection/collection_list.py index eea68c3d..9a527f26 100644 --- a/src/adcp/types/generated_poc/collection/collection_list.py +++ b/src/adcp/types/generated_poc/collection/collection_list.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/collection_list.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/collection_list_changed_webhook.py b/src/adcp/types/generated_poc/collection/collection_list_changed_webhook.py index 56c67ef8..59c625dc 100644 --- a/src/adcp/types/generated_poc/collection/collection_list_changed_webhook.py +++ b/src/adcp/types/generated_poc/collection/collection_list_changed_webhook.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/collection_list_changed_webhook.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -40,7 +40,9 @@ class CollectionListChangedWebhook(AdCPBaseModel): pattern="^[A-Za-z0-9_.:-]{16,255}$", ), ] - event: Annotated[Literal["collection_list_changed"], Field(description="The event type")] + event: Annotated[Literal["collection_list_changed"], Field(description="The event type")] = ( + "collection_list_changed" + ) list_id: Annotated[str, Field(description="ID of the collection list that changed")] list_name: Annotated[str | None, Field(description="Name of the collection list")] = None change_summary: Annotated[ diff --git a/src/adcp/types/generated_poc/collection/collection_list_filters.py b/src/adcp/types/generated_poc/collection/collection_list_filters.py index 31e7ea09..6610a092 100644 --- a/src/adcp/types/generated_poc/collection/collection_list_filters.py +++ b/src/adcp/types/generated_poc/collection/collection_list_filters.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/collection_list_filters.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/create_collection_list_request.py b/src/adcp/types/generated_poc/collection/create_collection_list_request.py index a52c3722..80663f49 100644 --- a/src/adcp/types/generated_poc/collection/create_collection_list_request.py +++ b/src/adcp/types/generated_poc/collection/create_collection_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/create_collection_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/create_collection_list_response.py b/src/adcp/types/generated_poc/collection/create_collection_list_response.py index 06558359..22cf031c 100644 --- a/src/adcp/types/generated_poc/collection/create_collection_list_response.py +++ b/src/adcp/types/generated_poc/collection/create_collection_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/create_collection_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/delete_collection_list_request.py b/src/adcp/types/generated_poc/collection/delete_collection_list_request.py index d3cdfaf7..91a3fac8 100644 --- a/src/adcp/types/generated_poc/collection/delete_collection_list_request.py +++ b/src/adcp/types/generated_poc/collection/delete_collection_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/delete_collection_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/delete_collection_list_response.py b/src/adcp/types/generated_poc/collection/delete_collection_list_response.py index b109eda5..f263ef33 100644 --- a/src/adcp/types/generated_poc/collection/delete_collection_list_response.py +++ b/src/adcp/types/generated_poc/collection/delete_collection_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/delete_collection_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/get_collection_list_request.py b/src/adcp/types/generated_poc/collection/get_collection_list_request.py index d1588b09..e947287f 100644 --- a/src/adcp/types/generated_poc/collection/get_collection_list_request.py +++ b/src/adcp/types/generated_poc/collection/get_collection_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/get_collection_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/get_collection_list_response.py b/src/adcp/types/generated_poc/collection/get_collection_list_response.py index 2887e8d9..a50bd605 100644 --- a/src/adcp/types/generated_poc/collection/get_collection_list_response.py +++ b/src/adcp/types/generated_poc/collection/get_collection_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/get_collection_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/list_collection_lists_request.py b/src/adcp/types/generated_poc/collection/list_collection_lists_request.py index 247b4ca0..4b042a8d 100644 --- a/src/adcp/types/generated_poc/collection/list_collection_lists_request.py +++ b/src/adcp/types/generated_poc/collection/list_collection_lists_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/list_collection_lists_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/list_collection_lists_response.py b/src/adcp/types/generated_poc/collection/list_collection_lists_response.py index 158fdd1d..576d23ad 100644 --- a/src/adcp/types/generated_poc/collection/list_collection_lists_response.py +++ b/src/adcp/types/generated_poc/collection/list_collection_lists_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/list_collection_lists_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/update_collection_list_request.py b/src/adcp/types/generated_poc/collection/update_collection_list_request.py index 41771da6..5a3bfa42 100644 --- a/src/adcp/types/generated_poc/collection/update_collection_list_request.py +++ b/src/adcp/types/generated_poc/collection/update_collection_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/update_collection_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/collection/update_collection_list_response.py b/src/adcp/types/generated_poc/collection/update_collection_list_response.py index 9586bd7c..c1e84333 100644 --- a/src/adcp/types/generated_poc/collection/update_collection_list_response.py +++ b/src/adcp/types/generated_poc/collection/update_collection_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: collection/update_collection_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/compliance/comply_test_controller_request.py b/src/adcp/types/generated_poc/compliance/comply_test_controller_request.py index 44dbbf8c..633f5a65 100644 --- a/src/adcp/types/generated_poc/compliance/comply_test_controller_request.py +++ b/src/adcp/types/generated_poc/compliance/comply_test_controller_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: compliance/comply_test_controller_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/compliance/comply_test_controller_response.py b/src/adcp/types/generated_poc/compliance/comply_test_controller_response.py index 39674016..498b37da 100644 --- a/src/adcp/types/generated_poc/compliance/comply_test_controller_response.py +++ b/src/adcp/types/generated_poc/compliance/comply_test_controller_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: compliance/comply_test_controller_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/artifact.py b/src/adcp/types/generated_poc/content_standards/artifact.py index 91f5f497..239b5708 100644 --- a/src/adcp/types/generated_poc/content_standards/artifact.py +++ b/src/adcp/types/generated_poc/content_standards/artifact.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/artifact.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -81,7 +81,7 @@ class Identifiers(AdCPBaseModel): class AssetAccess1(AdCPBaseModel): - method: Literal["bearer_token"] + method: Literal["bearer_token"] = "bearer_token" token: Annotated[str, Field(description="OAuth2 bearer token for Authorization header")] @@ -91,7 +91,7 @@ class Provider(Enum): class AssetAccess2(AdCPBaseModel): - method: Literal["service_account"] + method: Literal["service_account"] = "service_account" provider: Annotated[Provider, Field(description="Cloud provider")] credentials: Annotated[ dict[str, Any] | None, Field(description="Service account credentials") @@ -99,7 +99,7 @@ class AssetAccess2(AdCPBaseModel): class AssetAccess3(AdCPBaseModel): - method: Literal["signed_url"] + method: Literal["signed_url"] = "signed_url" class AssetAccess(RootModel[AssetAccess1 | AssetAccess2 | AssetAccess3]): @@ -116,7 +116,7 @@ def __getattr__(self, name: str) -> Any: class Assets(AdCPBaseModel): - type: Literal["text"] + type: Literal["text"] = "text" role: Annotated[ Role | None, Field( @@ -152,7 +152,7 @@ class Assets(AdCPBaseModel): class Assets1(AdCPBaseModel): - type: Literal["image"] + type: Literal["image"] = "image" url: Annotated[AnyUrl, Field(description="Image URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -168,7 +168,7 @@ class Assets1(AdCPBaseModel): class Assets2(AdCPBaseModel): - type: Literal["video"] + type: Literal["video"] = "video" url: Annotated[AnyUrl, Field(description="Video URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None @@ -198,7 +198,7 @@ class Assets2(AdCPBaseModel): class Assets3(AdCPBaseModel): - type: Literal["audio"] + type: Literal["audio"] = "audio" url: Annotated[AnyUrl, Field(description="Audio URL")] access: Annotated[AssetAccess | None, Field(description="Authentication for secured URLs")] = ( None diff --git a/src/adcp/types/generated_poc/content_standards/artifact_webhook_payload.py b/src/adcp/types/generated_poc/content_standards/artifact_webhook_payload.py index ed46a231..581e999c 100644 --- a/src/adcp/types/generated_poc/content_standards/artifact_webhook_payload.py +++ b/src/adcp/types/generated_poc/content_standards/artifact_webhook_payload.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/artifact_webhook_payload.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/calibrate_content_request.py b/src/adcp/types/generated_poc/content_standards/calibrate_content_request.py index 99dfe678..b35ef4ec 100644 --- a/src/adcp/types/generated_poc/content_standards/calibrate_content_request.py +++ b/src/adcp/types/generated_poc/content_standards/calibrate_content_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/calibrate_content_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/calibrate_content_response.py b/src/adcp/types/generated_poc/content_standards/calibrate_content_response.py index 6d26d258..8db3000b 100644 --- a/src/adcp/types/generated_poc/content_standards/calibrate_content_response.py +++ b/src/adcp/types/generated_poc/content_standards/calibrate_content_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/calibrate_content_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/content_standards.py b/src/adcp/types/generated_poc/content_standards/content_standards.py index 8a67d0b6..372c28dc 100644 --- a/src/adcp/types/generated_poc/content_standards/content_standards.py +++ b/src/adcp/types/generated_poc/content_standards/content_standards.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/content_standards.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/create_content_standards_request.py b/src/adcp/types/generated_poc/content_standards/create_content_standards_request.py index 6441052a..e3486ade 100644 --- a/src/adcp/types/generated_poc/content_standards/create_content_standards_request.py +++ b/src/adcp/types/generated_poc/content_standards/create_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/create_content_standards_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -44,7 +44,7 @@ class Scope(AdCPBaseModel): class Pass(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( @@ -57,7 +57,7 @@ class Pass(AdCPBaseModel): class Fail(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( diff --git a/src/adcp/types/generated_poc/content_standards/create_content_standards_response.py b/src/adcp/types/generated_poc/content_standards/create_content_standards_response.py index 42abe522..72b5cc17 100644 --- a/src/adcp/types/generated_poc/content_standards/create_content_standards_response.py +++ b/src/adcp/types/generated_poc/content_standards/create_content_standards_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/create_content_standards_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/get_content_standards_request.py b/src/adcp/types/generated_poc/content_standards/get_content_standards_request.py index 21acec9d..c8c69392 100644 --- a/src/adcp/types/generated_poc/content_standards/get_content_standards_request.py +++ b/src/adcp/types/generated_poc/content_standards/get_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/get_content_standards_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_request.py b/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_request.py index d4030157..b4d62e7f 100644 --- a/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_request.py +++ b/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/get_media_buy_artifacts_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_response.py b/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_response.py index 59630246..b242e875 100644 --- a/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_response.py +++ b/src/adcp/types/generated_poc/content_standards/get_media_buy_artifacts_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/get_media_buy_artifacts_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/list_content_standards_request.py b/src/adcp/types/generated_poc/content_standards/list_content_standards_request.py index 95f584e8..be6aaf07 100644 --- a/src/adcp/types/generated_poc/content_standards/list_content_standards_request.py +++ b/src/adcp/types/generated_poc/content_standards/list_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/list_content_standards_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/list_content_standards_response.py b/src/adcp/types/generated_poc/content_standards/list_content_standards_response.py index 3b56e280..6e07c933 100644 --- a/src/adcp/types/generated_poc/content_standards/list_content_standards_response.py +++ b/src/adcp/types/generated_poc/content_standards/list_content_standards_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/list_content_standards_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/update_content_standards_request.py b/src/adcp/types/generated_poc/content_standards/update_content_standards_request.py index 851ddba6..ada3fb35 100644 --- a/src/adcp/types/generated_poc/content_standards/update_content_standards_request.py +++ b/src/adcp/types/generated_poc/content_standards/update_content_standards_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/update_content_standards_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -44,7 +44,7 @@ class Scope(AdCPBaseModel): class Pass(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( @@ -57,7 +57,7 @@ class Pass(AdCPBaseModel): class Fail(AdCPBaseModel): - type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] + type: Annotated[Literal["url"], Field(description="Indicates this is a URL reference")] = "url" value: Annotated[ AnyUrl, Field( diff --git a/src/adcp/types/generated_poc/content_standards/update_content_standards_response.py b/src/adcp/types/generated_poc/content_standards/update_content_standards_response.py index 0bd1fbfc..015b9690 100644 --- a/src/adcp/types/generated_poc/content_standards/update_content_standards_response.py +++ b/src/adcp/types/generated_poc/content_standards/update_content_standards_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/update_content_standards_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/validate_content_delivery_request.py b/src/adcp/types/generated_poc/content_standards/validate_content_delivery_request.py index 7fdc9e8a..f2d9cbb3 100644 --- a/src/adcp/types/generated_poc/content_standards/validate_content_delivery_request.py +++ b/src/adcp/types/generated_poc/content_standards/validate_content_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/validate_content_delivery_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/content_standards/validate_content_delivery_response.py b/src/adcp/types/generated_poc/content_standards/validate_content_delivery_response.py index 0d212156..aa757462 100644 --- a/src/adcp/types/generated_poc/content_standards/validate_content_delivery_response.py +++ b/src/adcp/types/generated_poc/content_standards/validate_content_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/validate_content_delivery_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/account.py b/src/adcp/types/generated_poc/core/account.py index d14f7001..b6b4aabe 100644 --- a/src/adcp/types/generated_poc/core/account.py +++ b/src/adcp/types/generated_poc/core/account.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/account.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/account_ref.py b/src/adcp/types/generated_poc/core/account_ref.py index 9664fcf0..dc6b35f1 100644 --- a/src/adcp/types/generated_poc/core/account_ref.py +++ b/src/adcp/types/generated_poc/core/account_ref.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/account_ref.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/activation_key.py b/src/adcp/types/generated_poc/core/activation_key.py index fffda749..ca24c30c 100644 --- a/src/adcp/types/generated_poc/core/activation_key.py +++ b/src/adcp/types/generated_poc/core/activation_key.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/activation_key.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -14,7 +14,9 @@ class ActivationKey4(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - type: Annotated[Literal["segment_id"], Field(description="Segment ID based targeting")] + type: Annotated[Literal["segment_id"], Field(description="Segment ID based targeting")] = ( + "segment_id" + ) segment_id: Annotated[ str, Field(description="The platform-specific segment identifier to use in campaign targeting"), @@ -25,7 +27,9 @@ class ActivationKey5(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - type: Annotated[Literal["key_value"], Field(description="Key-value pair based targeting")] + type: Annotated[Literal["key_value"], Field(description="Key-value pair based targeting")] = ( + "key_value" + ) key: Annotated[str, Field(description="The targeting parameter key")] value: Annotated[str, Field(description="The targeting parameter value")] diff --git a/src/adcp/types/generated_poc/core/ad_inventory_config.py b/src/adcp/types/generated_poc/core/ad_inventory_config.py index 26d17d45..c63a9dab 100644 --- a/src/adcp/types/generated_poc/core/ad_inventory_config.py +++ b/src/adcp/types/generated_poc/core/ad_inventory_config.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/ad_inventory_config.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/agent_encryption_key.py b/src/adcp/types/generated_poc/core/agent_encryption_key.py index edf2e306..d6f41dac 100644 --- a/src/adcp/types/generated_poc/core/agent_encryption_key.py +++ b/src/adcp/types/generated_poc/core/agent_encryption_key.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/agent_encryption_key.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -21,11 +21,13 @@ class AgentEncryptionKey(AdCPBaseModel): max_length=8, ), ] - kty: Annotated[Literal["OKP"], Field(description="JWK key type. Must be OKP for X25519.")] + kty: Annotated[Literal["OKP"], Field(description="JWK key type. Must be OKP for X25519.")] = ( + "OKP" + ) crv: Annotated[ Literal["X25519"], Field(description="Curve name. Must be X25519 for TMPX encryption.") - ] + ] = "X25519" use: Annotated[ Literal["enc"], Field(description="JWK use value. Must be enc for encryption keys.") - ] + ] = "enc" x: Annotated[str, Field(description="Base64url-encoded X25519 public key (32 bytes).")] diff --git a/src/adcp/types/generated_poc/core/agent_signing_key.py b/src/adcp/types/generated_poc/core/agent_signing_key.py index a410a2b1..a7507c46 100644 --- a/src/adcp/types/generated_poc/core/agent_signing_key.py +++ b/src/adcp/types/generated_poc/core/agent_signing_key.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/agent_signing_key.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/app_item.py b/src/adcp/types/generated_poc/core/app_item.py index 07771809..ddd91d9e 100644 --- a/src/adcp/types/generated_poc/core/app_item.py +++ b/src/adcp/types/generated_poc/core/app_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/app_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/assets/audio_asset.py b/src/adcp/types/generated_poc/core/assets/audio_asset.py index 3bfbc636..cd74e12d 100644 --- a/src/adcp/types/generated_poc/core/assets/audio_asset.py +++ b/src/adcp/types/generated_poc/core/assets/audio_asset.py @@ -1,11 +1,11 @@ # generated by datamodel-codegen: # filename: core/assets/audio_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations from enum import Enum, IntEnum -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, ConfigDict, Field @@ -30,6 +30,12 @@ class AudioAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["audio"], + Field( + description="Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry." + ), + ] = "audio" url: Annotated[AnyUrl, Field(description="URL to the audio asset")] duration_ms: Annotated[ int | None, Field(description="Audio duration in milliseconds", ge=0) diff --git a/src/adcp/types/generated_poc/core/assets/brief_asset.py b/src/adcp/types/generated_poc/core/assets/brief_asset.py index 10013976..5e3dbfb2 100644 --- a/src/adcp/types/generated_poc/core/assets/brief_asset.py +++ b/src/adcp/types/generated_poc/core/assets/brief_asset.py @@ -1,11 +1,20 @@ # generated by datamodel-codegen: # filename: core/assets/brief_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations +from typing import Annotated, Literal + +from pydantic import Field + from ..creative_brief import CreativeBrief class BriefAsset(CreativeBrief): - pass + asset_type: Annotated[ + Literal["brief"], + Field( + description="Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry." + ), + ] = "brief" diff --git a/src/adcp/types/generated_poc/core/assets/catalog_asset.py b/src/adcp/types/generated_poc/core/assets/catalog_asset.py index 274aee8f..dd67c7ab 100644 --- a/src/adcp/types/generated_poc/core/assets/catalog_asset.py +++ b/src/adcp/types/generated_poc/core/assets/catalog_asset.py @@ -1,11 +1,20 @@ # generated by datamodel-codegen: # filename: core/assets/catalog_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations +from typing import Annotated, Literal + +from pydantic import Field + from ..catalog import Catalog class CatalogAsset(Catalog): - pass + asset_type: Annotated[ + Literal["catalog"], + Field( + description="Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry." + ), + ] = "catalog" diff --git a/src/adcp/types/generated_poc/core/assets/css_asset.py b/src/adcp/types/generated_poc/core/assets/css_asset.py index 6e7aa78a..83ee8d13 100644 --- a/src/adcp/types/generated_poc/core/assets/css_asset.py +++ b/src/adcp/types/generated_poc/core/assets/css_asset.py @@ -1,10 +1,10 @@ # generated by datamodel-codegen: # filename: core/assets/css_asset.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field @@ -16,6 +16,12 @@ class CssAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["css"], + Field( + description="Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry." + ), + ] = "css" content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") diff --git a/src/adcp/types/generated_poc/core/assets/daast_asset.py b/src/adcp/types/generated_poc/core/assets/daast_asset.py index c4f96569..8676028b 100644 --- a/src/adcp/types/generated_poc/core/assets/daast_asset.py +++ b/src/adcp/types/generated_poc/core/assets/daast_asset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/assets/daast_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -18,11 +18,12 @@ class DaastAsset1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ daast_version_1.DaastVersion | None, Field(description="DAAST specification version") ] = None @@ -45,17 +46,23 @@ class DaastAsset1(AdCPBaseModel): description="Provenance metadata for this asset, overrides manifest-level provenance" ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DaastAsset2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating DAAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline DAAST XML content")] + asset_type: Annotated[ + Literal["daast"], + Field( + description="Discriminator identifying this as a DAAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "daast" daast_version: Annotated[ daast_version_1.DaastVersion | None, Field(description="DAAST specification version") ] = None @@ -78,6 +85,11 @@ class DaastAsset2(AdCPBaseModel): description="Provenance metadata for this asset, overrides manifest-level provenance" ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline DAAST XML content")] class DaastAsset(RootModel[DaastAsset1 | DaastAsset2]): @@ -85,6 +97,7 @@ class DaastAsset(RootModel[DaastAsset1 | DaastAsset2]): DaastAsset1 | DaastAsset2, Field( description="DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", + discriminator="delivery_type", title="DAAST Asset", ), ] diff --git a/src/adcp/types/generated_poc/core/assets/html_asset.py b/src/adcp/types/generated_poc/core/assets/html_asset.py index d11fdd60..a95d5a5f 100644 --- a/src/adcp/types/generated_poc/core/assets/html_asset.py +++ b/src/adcp/types/generated_poc/core/assets/html_asset.py @@ -1,10 +1,10 @@ # generated by datamodel-codegen: # filename: core/assets/html_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field @@ -34,6 +34,12 @@ class HtmlAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["html"], + Field( + description="Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry." + ), + ] = "html" content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None accessibility: Annotated[ diff --git a/src/adcp/types/generated_poc/core/assets/image_asset.py b/src/adcp/types/generated_poc/core/assets/image_asset.py index dd679f26..b85b66b5 100644 --- a/src/adcp/types/generated_poc/core/assets/image_asset.py +++ b/src/adcp/types/generated_poc/core/assets/image_asset.py @@ -1,10 +1,10 @@ # generated by datamodel-codegen: # filename: core/assets/image_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, ConfigDict, Field @@ -16,6 +16,12 @@ class ImageAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["image"], + Field( + description="Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry." + ), + ] = "image" url: Annotated[AnyUrl, Field(description="URL to the image asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] diff --git a/src/adcp/types/generated_poc/core/assets/javascript_asset.py b/src/adcp/types/generated_poc/core/assets/javascript_asset.py index f46ad936..8a0f5d42 100644 --- a/src/adcp/types/generated_poc/core/assets/javascript_asset.py +++ b/src/adcp/types/generated_poc/core/assets/javascript_asset.py @@ -1,10 +1,10 @@ # generated by datamodel-codegen: # filename: core/assets/javascript_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field @@ -35,6 +35,12 @@ class JavascriptAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["javascript"], + Field( + description="Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry." + ), + ] = "javascript" content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ javascript_module_type.JavascriptModuleType | None, diff --git a/src/adcp/types/generated_poc/core/assets/markdown_asset.py b/src/adcp/types/generated_poc/core/assets/markdown_asset.py index 4f0ce09b..d7ed1d84 100644 --- a/src/adcp/types/generated_poc/core/assets/markdown_asset.py +++ b/src/adcp/types/generated_poc/core/assets/markdown_asset.py @@ -1,10 +1,10 @@ # generated by datamodel-codegen: # filename: core/assets/markdown_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field @@ -16,6 +16,12 @@ class MarkdownAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["markdown"], + Field( + description="Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry." + ), + ] = "markdown" content: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/core/assets/text_asset.py b/src/adcp/types/generated_poc/core/assets/text_asset.py index 10756f30..0d2eda73 100644 --- a/src/adcp/types/generated_poc/core/assets/text_asset.py +++ b/src/adcp/types/generated_poc/core/assets/text_asset.py @@ -1,10 +1,10 @@ # generated by datamodel-codegen: # filename: core/assets/text_asset.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field @@ -16,6 +16,12 @@ class TextAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["text"], + Field( + description="Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry." + ), + ] = "text" content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None diff --git a/src/adcp/types/generated_poc/core/assets/url_asset.py b/src/adcp/types/generated_poc/core/assets/url_asset.py index e09899c0..8ef0be77 100644 --- a/src/adcp/types/generated_poc/core/assets/url_asset.py +++ b/src/adcp/types/generated_poc/core/assets/url_asset.py @@ -1,13 +1,13 @@ # generated by datamodel-codegen: # filename: core/assets/url_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel -from pydantic import AnyUrl, ConfigDict, Field +from pydantic import ConfigDict, Field from ...enums import url_asset_type from .. import provenance as provenance_1 @@ -17,7 +17,18 @@ class UrlAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - url: Annotated[AnyUrl, Field(description="URL reference")] + asset_type: Annotated[ + Literal["url"], + Field( + description="Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry." + ), + ] = "url" + url: Annotated[ + str, + Field( + description="URL reference. May be a plain URI or an RFC 6570 URI template carrying AdCP universal macros (e.g., `{SKU}`, `{MEDIA_BUY_ID}`). Buyers MUST NOT pre-encode macro braces at sync time; the ad server URL-encodes substituted values at impression time. See docs/creative/universal-macros.mdx." + ), + ] url_type: Annotated[ url_asset_type.UrlAssetType | None, Field( diff --git a/src/adcp/types/generated_poc/core/assets/vast_asset.py b/src/adcp/types/generated_poc/core/assets/vast_asset.py index 523f4b0f..a9283c1e 100644 --- a/src/adcp/types/generated_poc/core/assets/vast_asset.py +++ b/src/adcp/types/generated_poc/core/assets/vast_asset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/assets/vast_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -18,11 +18,12 @@ class VastAsset1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["url"], - Field(description="Discriminator indicating VAST is delivered via URL endpoint"), - ] - url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ vast_version_1.VastVersion | None, Field(description="VAST specification version") ] = None @@ -50,17 +51,23 @@ class VastAsset1(AdCPBaseModel): description="Provenance metadata for this asset, overrides manifest-level provenance" ), ] = None + delivery_type: Annotated[ + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), + ] = "url" + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] class VastAsset2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - delivery_type: Annotated[ - Literal["inline"], - Field(description="Discriminator indicating VAST is delivered as inline XML content"), - ] - content: Annotated[str, Field(description="Inline VAST XML content")] + asset_type: Annotated[ + Literal["vast"], + Field( + description="Discriminator identifying this as a VAST asset. See /schemas/creative/asset-types for the registry." + ), + ] = "vast" vast_version: Annotated[ vast_version_1.VastVersion | None, Field(description="VAST specification version") ] = None @@ -88,6 +95,11 @@ class VastAsset2(AdCPBaseModel): description="Provenance metadata for this asset, overrides manifest-level provenance" ), ] = None + delivery_type: Annotated[ + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), + ] = "inline" + content: Annotated[str, Field(description="Inline VAST XML content")] class VastAsset(RootModel[VastAsset1 | VastAsset2]): @@ -95,6 +107,7 @@ class VastAsset(RootModel[VastAsset1 | VastAsset2]): VastAsset1 | VastAsset2, Field( description="VAST (Video Ad Serving Template) tag for third-party video ad serving", + discriminator="delivery_type", title="VAST Asset", ), ] diff --git a/src/adcp/types/generated_poc/core/assets/video_asset.py b/src/adcp/types/generated_poc/core/assets/video_asset.py index ec669ecc..626043c6 100644 --- a/src/adcp/types/generated_poc/core/assets/video_asset.py +++ b/src/adcp/types/generated_poc/core/assets/video_asset.py @@ -1,11 +1,11 @@ # generated by datamodel-codegen: # filename: core/assets/video_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations from enum import Enum, IntEnum -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, ConfigDict, Field @@ -78,6 +78,12 @@ class VideoAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["video"], + Field( + description="Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry." + ), + ] = "video" url: Annotated[AnyUrl, Field(description="URL to the video asset")] width: Annotated[int, Field(description="Width in pixels", ge=1)] height: Annotated[int, Field(description="Height in pixels", ge=1)] diff --git a/src/adcp/types/generated_poc/core/assets/webhook_asset.py b/src/adcp/types/generated_poc/core/assets/webhook_asset.py index be012575..fcde873a 100644 --- a/src/adcp/types/generated_poc/core/assets/webhook_asset.py +++ b/src/adcp/types/generated_poc/core/assets/webhook_asset.py @@ -1,10 +1,10 @@ # generated by datamodel-codegen: # filename: core/assets/webhook_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, ConfigDict, Field @@ -29,6 +29,12 @@ class WebhookAsset(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) + asset_type: Annotated[ + Literal["webhook"], + Field( + description="Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry." + ), + ] = "webhook" url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] method: Annotated[http_method.HttpMethod | None, Field(description="HTTP method")] = ( http_method.HttpMethod.POST diff --git a/src/adcp/types/generated_poc/core/async_response_data.py b/src/adcp/types/generated_poc/core/async_response_data.py index 6d1a5af2..8d84341a 100644 --- a/src/adcp/types/generated_poc/core/async_response_data.py +++ b/src/adcp/types/generated_poc/core/async_response_data.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/async_response_data.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/attribution_window.py b/src/adcp/types/generated_poc/core/attribution_window.py index 7c55e859..12f5b58b 100644 --- a/src/adcp/types/generated_poc/core/attribution_window.py +++ b/src/adcp/types/generated_poc/core/attribution_window.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/attribution_window.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/audience_member.py b/src/adcp/types/generated_poc/core/audience_member.py index 50686312..5819727f 100644 --- a/src/adcp/types/generated_poc/core/audience_member.py +++ b/src/adcp/types/generated_poc/core/audience_member.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/audience_member.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/audience_selector.py b/src/adcp/types/generated_poc/core/audience_selector.py index b53adc0a..03a159d4 100644 --- a/src/adcp/types/generated_poc/core/audience_selector.py +++ b/src/adcp/types/generated_poc/core/audience_selector.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/audience_selector.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -18,7 +18,7 @@ class AudienceSelector4(AdCPBaseModel): ) type: Annotated[ Literal["description"], Field(description="Discriminator for description-based selectors") - ] + ] = "description" description: Annotated[ str, Field( @@ -41,9 +41,11 @@ class AudienceSelector1(AdCPBaseModel): ) type: Annotated[ Literal["signal"], Field(description="Discriminator for signal-based selectors") - ] + ] = "signal" signal_id: Annotated[signal_id_1.SignalId, Field(description="The signal to target")] - value_type: Annotated[Literal["binary"], Field(description="Discriminator for binary signals")] + value_type: Annotated[ + Literal["binary"], Field(description="Discriminator for binary signals") + ] = "binary" value: Annotated[ bool, Field( @@ -58,11 +60,11 @@ class AudienceSelector2(AdCPBaseModel): ) type: Annotated[ Literal["signal"], Field(description="Discriminator for signal-based selectors") - ] + ] = "signal" signal_id: Annotated[signal_id_1.SignalId, Field(description="The signal to target")] value_type: Annotated[ Literal["categorical"], Field(description="Discriminator for categorical signals") - ] + ] = "categorical" values: Annotated[ list[str], Field( @@ -78,11 +80,11 @@ class AudienceSelector3(AdCPBaseModel): ) type: Annotated[ Literal["signal"], Field(description="Discriminator for signal-based selectors") - ] + ] = "signal" signal_id: Annotated[signal_id_1.SignalId, Field(description="The signal to target")] value_type: Annotated[ Literal["numeric"], Field(description="Discriminator for numeric signals") - ] + ] = "numeric" min_value: Annotated[ float | None, Field( diff --git a/src/adcp/types/generated_poc/core/brand_id.py b/src/adcp/types/generated_poc/core/brand_id.py index 8046ba62..b38824ff 100644 --- a/src/adcp/types/generated_poc/core/brand_id.py +++ b/src/adcp/types/generated_poc/core/brand_id.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/brand_id.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/brand_ref.py b/src/adcp/types/generated_poc/core/brand_ref.py index 91b8cffd..245cb872 100644 --- a/src/adcp/types/generated_poc/core/brand_ref.py +++ b/src/adcp/types/generated_poc/core/brand_ref.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/brand_ref.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/business_entity.py b/src/adcp/types/generated_poc/core/business_entity.py index 88ab5f05..b2e2cc4a 100644 --- a/src/adcp/types/generated_poc/core/business_entity.py +++ b/src/adcp/types/generated_poc/core/business_entity.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/business_entity.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/cancellation_policy.py b/src/adcp/types/generated_poc/core/cancellation_policy.py index 2ba5adf4..aedd9943 100644 --- a/src/adcp/types/generated_poc/core/cancellation_policy.py +++ b/src/adcp/types/generated_poc/core/cancellation_policy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/cancellation_policy.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/catalog.py b/src/adcp/types/generated_poc/core/catalog.py index 66153d72..b43842d8 100644 --- a/src/adcp/types/generated_poc/core/catalog.py +++ b/src/adcp/types/generated_poc/core/catalog.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/catalog.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/catalog_field_mapping.py b/src/adcp/types/generated_poc/core/catalog_field_mapping.py index 701729c8..c7a55157 100644 --- a/src/adcp/types/generated_poc/core/catalog_field_mapping.py +++ b/src/adcp/types/generated_poc/core/catalog_field_mapping.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/catalog_field_mapping.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/catchment.py b/src/adcp/types/generated_poc/core/catchment.py index 5e7e2299..96e89cf6 100644 --- a/src/adcp/types/generated_poc/core/catchment.py +++ b/src/adcp/types/generated_poc/core/catchment.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/catchment.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/collection.py b/src/adcp/types/generated_poc/core/collection.py index b3929e73..51d09230 100644 --- a/src/adcp/types/generated_poc/core/collection.py +++ b/src/adcp/types/generated_poc/core/collection.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/collection.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/collection_distribution.py b/src/adcp/types/generated_poc/core/collection_distribution.py index 1de40811..47ca6336 100644 --- a/src/adcp/types/generated_poc/core/collection_distribution.py +++ b/src/adcp/types/generated_poc/core/collection_distribution.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/collection_distribution.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/collection_list_ref.py b/src/adcp/types/generated_poc/core/collection_list_ref.py index 31bd04a4..7c89dc7c 100644 --- a/src/adcp/types/generated_poc/core/collection_list_ref.py +++ b/src/adcp/types/generated_poc/core/collection_list_ref.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/collection_list_ref.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/collection_selector.py b/src/adcp/types/generated_poc/core/collection_selector.py index ce9922fa..45709775 100644 --- a/src/adcp/types/generated_poc/core/collection_selector.py +++ b/src/adcp/types/generated_poc/core/collection_selector.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/collection_selector.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/content_rating.py b/src/adcp/types/generated_poc/core/content_rating.py index 1a339eb2..8fb1cf31 100644 --- a/src/adcp/types/generated_poc/core/content_rating.py +++ b/src/adcp/types/generated_poc/core/content_rating.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/content_rating.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/context.py b/src/adcp/types/generated_poc/core/context.py index a56ba9d7..f0f1ec4c 100644 --- a/src/adcp/types/generated_poc/core/context.py +++ b/src/adcp/types/generated_poc/core/context.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/context.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/creative_asset.py b/src/adcp/types/generated_poc/core/creative_asset.py index 1b3adee2..ae9920d2 100644 --- a/src/adcp/types/generated_poc/core/creative_asset.py +++ b/src/adcp/types/generated_poc/core/creative_asset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -75,7 +75,9 @@ class CreativeAsset(AdCPBaseModel): | brief_asset.BriefAsset | catalog_asset.CatalogAsset, ], - Field(description="Assets required by the format, keyed by asset_id"), + Field( + description="Assets required by the format, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] inputs: Annotated[ list[Input] | None, diff --git a/src/adcp/types/generated_poc/core/creative_assignment.py b/src/adcp/types/generated_poc/core/creative_assignment.py index 6c9e9985..55de53e1 100644 --- a/src/adcp/types/generated_poc/core/creative_assignment.py +++ b/src/adcp/types/generated_poc/core/creative_assignment.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_assignment.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/creative_brief.py b/src/adcp/types/generated_poc/core/creative_brief.py index 45ad1973..9c4f2176 100644 --- a/src/adcp/types/generated_poc/core/creative_brief.py +++ b/src/adcp/types/generated_poc/core/creative_brief.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_brief.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/creative_consumption.py b/src/adcp/types/generated_poc/core/creative_consumption.py index 7dc9be2d..1d7b461c 100644 --- a/src/adcp/types/generated_poc/core/creative_consumption.py +++ b/src/adcp/types/generated_poc/core/creative_consumption.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_consumption.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/creative_filters.py b/src/adcp/types/generated_poc/core/creative_filters.py index 9b605661..4986167f 100644 --- a/src/adcp/types/generated_poc/core/creative_filters.py +++ b/src/adcp/types/generated_poc/core/creative_filters.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_filters.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/creative_item.py b/src/adcp/types/generated_poc/core/creative_item.py index ce8116e1..4d0651ba 100644 --- a/src/adcp/types/generated_poc/core/creative_item.py +++ b/src/adcp/types/generated_poc/core/creative_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -17,7 +17,7 @@ class CreativeItem1(AdCPBaseModel): asset_kind: Annotated[ Literal["media"], Field(description="Discriminator indicating this is a media asset with content_uri"), - ] + ] = "media" asset_type: Annotated[ str, Field( @@ -37,7 +37,7 @@ class CreativeItem2(AdCPBaseModel): asset_kind: Annotated[ Literal["text"], Field(description="Discriminator indicating this is a text asset with content"), - ] + ] = "text" asset_type: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/core/creative_manifest.py b/src/adcp/types/generated_poc/core/creative_manifest.py index 6b5270f1..5abc0050 100644 --- a/src/adcp/types/generated_poc/core/creative_manifest.py +++ b/src/adcp/types/generated_poc/core/creative_manifest.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_manifest.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -61,7 +61,7 @@ class CreativeManifest(AdCPBaseModel): | catalog_asset.CatalogAsset, ], Field( - description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Full validation requires format context. The format defines what type each asset_id should be. Standalone schema validation only checks structural conformance — each asset must match at least one valid asset type schema." + description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nEach asset value carries an `asset_type` discriminator (image, video, audio, vast, daast, text, markdown, url, html, css, webhook, javascript, brief, catalog) that selects the matching asset schema. Validators with OpenAPI-style discriminator support use `asset_type` to report errors against only the selected branch instead of all branches." ), ] rights: Annotated[ diff --git a/src/adcp/types/generated_poc/core/creative_policy.py b/src/adcp/types/generated_poc/core/creative_policy.py index 4df1415d..f8cb4065 100644 --- a/src/adcp/types/generated_poc/core/creative_policy.py +++ b/src/adcp/types/generated_poc/core/creative_policy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_policy.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/creative_variable.py b/src/adcp/types/generated_poc/core/creative_variable.py index 3b195138..4bd20a05 100644 --- a/src/adcp/types/generated_poc/core/creative_variable.py +++ b/src/adcp/types/generated_poc/core/creative_variable.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_variable.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/creative_variant.py b/src/adcp/types/generated_poc/core/creative_variant.py index bdece66d..18400fcd 100644 --- a/src/adcp/types/generated_poc/core/creative_variant.py +++ b/src/adcp/types/generated_poc/core/creative_variant.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_variant.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/data_provider_signal_selector.py b/src/adcp/types/generated_poc/core/data_provider_signal_selector.py index 219a8a7a..f2193a0f 100644 --- a/src/adcp/types/generated_poc/core/data_provider_signal_selector.py +++ b/src/adcp/types/generated_poc/core/data_provider_signal_selector.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/data_provider_signal_selector.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -26,7 +26,7 @@ class DataProviderSignalSelector1(AdCPBaseModel): Field( description="Discriminator indicating all signals from this data provider are included" ), - ] + ] = "all" class SignalId(RootModel[str]): @@ -47,7 +47,7 @@ class DataProviderSignalSelector2(AdCPBaseModel): selection_type: Annotated[ Literal["by_id"], Field(description="Discriminator indicating selection by specific signal IDs"), - ] + ] = "by_id" signal_ids: Annotated[ list[SignalId], Field(description="Specific signal IDs from the data provider's catalog", min_length=1), @@ -71,7 +71,7 @@ class DataProviderSignalSelector3(AdCPBaseModel): ] selection_type: Annotated[ Literal["by_tag"], Field(description="Discriminator indicating selection by signal tags") - ] + ] = "by_tag" signal_tags: Annotated[ list[SignalTag], Field( diff --git a/src/adcp/types/generated_poc/core/date_range.py b/src/adcp/types/generated_poc/core/date_range.py index 91dfb731..6059c1b0 100644 --- a/src/adcp/types/generated_poc/core/date_range.py +++ b/src/adcp/types/generated_poc/core/date_range.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/date_range.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/datetime_range.py b/src/adcp/types/generated_poc/core/datetime_range.py index 39f95aa9..091e9aba 100644 --- a/src/adcp/types/generated_poc/core/datetime_range.py +++ b/src/adcp/types/generated_poc/core/datetime_range.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/datetime_range.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/daypart_target.py b/src/adcp/types/generated_poc/core/daypart_target.py index c44af0ad..f3c3b9fa 100644 --- a/src/adcp/types/generated_poc/core/daypart_target.py +++ b/src/adcp/types/generated_poc/core/daypart_target.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/daypart_target.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/deadline_policy.py b/src/adcp/types/generated_poc/core/deadline_policy.py index 9944fa1f..a87d1c2a 100644 --- a/src/adcp/types/generated_poc/core/deadline_policy.py +++ b/src/adcp/types/generated_poc/core/deadline_policy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/deadline_policy.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/delivery_forecast.py b/src/adcp/types/generated_poc/core/delivery_forecast.py index 0f763c8a..467fabcf 100644 --- a/src/adcp/types/generated_poc/core/delivery_forecast.py +++ b/src/adcp/types/generated_poc/core/delivery_forecast.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/delivery_forecast.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/delivery_metrics.py b/src/adcp/types/generated_poc/core/delivery_metrics.py index ba3afb1f..369b3eb1 100644 --- a/src/adcp/types/generated_poc/core/delivery_metrics.py +++ b/src/adcp/types/generated_poc/core/delivery_metrics.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/delivery_metrics.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/deployment.py b/src/adcp/types/generated_poc/core/deployment.py index 6105ad5d..61c414b3 100644 --- a/src/adcp/types/generated_poc/core/deployment.py +++ b/src/adcp/types/generated_poc/core/deployment.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/deployment.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -19,7 +19,7 @@ class Deployment1(AdCPBaseModel): type: Annotated[ Literal["platform"], Field(description="Discriminator indicating this is a platform-based deployment"), - ] + ] = "platform" platform: Annotated[str, Field(description="Platform identifier for DSPs")] account: Annotated[str | None, Field(description="Account identifier if applicable")] = None is_live: Annotated[ @@ -51,7 +51,7 @@ class Deployment2(AdCPBaseModel): type: Annotated[ Literal["agent"], Field(description="Discriminator indicating this is an agent URL-based deployment"), - ] + ] = "agent" agent_url: Annotated[AnyUrl, Field(description="URL identifying the deployment agent")] account: Annotated[str | None, Field(description="Account identifier if applicable")] = None is_live: Annotated[ diff --git a/src/adcp/types/generated_poc/core/destination.py b/src/adcp/types/generated_poc/core/destination.py index d8d152b0..c4185fa2 100644 --- a/src/adcp/types/generated_poc/core/destination.py +++ b/src/adcp/types/generated_poc/core/destination.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/destination.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -17,7 +17,7 @@ class Destination1(AdCPBaseModel): type: Annotated[ Literal["platform"], Field(description="Discriminator indicating this is a platform-based deployment"), - ] + ] = "platform" platform: Annotated[ str, Field(description="Platform identifier for DSPs (e.g., 'the-trade-desk', 'amazon-dsp')"), @@ -34,7 +34,7 @@ class Destination2(AdCPBaseModel): type: Annotated[ Literal["agent"], Field(description="Discriminator indicating this is an agent URL-based deployment"), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field(description="URL identifying the deployment agent (for sales agents, etc.)") ] diff --git a/src/adcp/types/generated_poc/core/destination_item.py b/src/adcp/types/generated_poc/core/destination_item.py index 7689cfe9..d8ef318c 100644 --- a/src/adcp/types/generated_poc/core/destination_item.py +++ b/src/adcp/types/generated_poc/core/destination_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/destination_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/diagnostic_issue.py b/src/adcp/types/generated_poc/core/diagnostic_issue.py index 4d2fd18b..f8c18623 100644 --- a/src/adcp/types/generated_poc/core/diagnostic_issue.py +++ b/src/adcp/types/generated_poc/core/diagnostic_issue.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/diagnostic_issue.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/duration.py b/src/adcp/types/generated_poc/core/duration.py index a399bb0f..e58373ae 100644 --- a/src/adcp/types/generated_poc/core/duration.py +++ b/src/adcp/types/generated_poc/core/duration.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/duration.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/education_item.py b/src/adcp/types/generated_poc/core/education_item.py index b4673760..f05a5404 100644 --- a/src/adcp/types/generated_poc/core/education_item.py +++ b/src/adcp/types/generated_poc/core/education_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/education_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/error.py b/src/adcp/types/generated_poc/core/error.py index 69e59593..22d80d0b 100644 --- a/src/adcp/types/generated_poc/core/error.py +++ b/src/adcp/types/generated_poc/core/error.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/error.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/event.py b/src/adcp/types/generated_poc/core/event.py index e77b7245..902e5cf0 100644 --- a/src/adcp/types/generated_poc/core/event.py +++ b/src/adcp/types/generated_poc/core/event.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/event.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/event_custom_data.py b/src/adcp/types/generated_poc/core/event_custom_data.py index 5053aa85..98f450a1 100644 --- a/src/adcp/types/generated_poc/core/event_custom_data.py +++ b/src/adcp/types/generated_poc/core/event_custom_data.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/event_custom_data.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/event_source_health.py b/src/adcp/types/generated_poc/core/event_source_health.py index 600380ce..a5887159 100644 --- a/src/adcp/types/generated_poc/core/event_source_health.py +++ b/src/adcp/types/generated_poc/core/event_source_health.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/event_source_health.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/ext.py b/src/adcp/types/generated_poc/core/ext.py index c712ed26..53933cbe 100644 --- a/src/adcp/types/generated_poc/core/ext.py +++ b/src/adcp/types/generated_poc/core/ext.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/ext.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/feature_requirement.py b/src/adcp/types/generated_poc/core/feature_requirement.py index ea54b82f..0f040af1 100644 --- a/src/adcp/types/generated_poc/core/feature_requirement.py +++ b/src/adcp/types/generated_poc/core/feature_requirement.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/feature_requirement.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/flight_item.py b/src/adcp/types/generated_poc/core/flight_item.py index b3951645..4264dc24 100644 --- a/src/adcp/types/generated_poc/core/flight_item.py +++ b/src/adcp/types/generated_poc/core/flight_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/flight_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/forecast_point.py b/src/adcp/types/generated_poc/core/forecast_point.py index 6694e882..fa374ff5 100644 --- a/src/adcp/types/generated_poc/core/forecast_point.py +++ b/src/adcp/types/generated_poc/core/forecast_point.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/forecast_point.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/forecast_range.py b/src/adcp/types/generated_poc/core/forecast_range.py index 03026794..2e7f9782 100644 --- a/src/adcp/types/generated_poc/core/forecast_range.py +++ b/src/adcp/types/generated_poc/core/forecast_range.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/forecast_range.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/format.py b/src/adcp/types/generated_poc/core/format.py index d858465a..95fc25e3 100644 --- a/src/adcp/types/generated_poc/core/format.py +++ b/src/adcp/types/generated_poc/core/format.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/format.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -201,7 +201,7 @@ class BaseIndividualAsset(AdCPBaseModel): item_type: Annotated[ Literal["individual"], Field(description="Discriminator indicating this is an individual asset"), - ] + ] = "individual" asset_id: Annotated[ str, Field( @@ -395,7 +395,7 @@ class Assets94(AdCPBaseModel): item_type: Annotated[ Literal["repeatable_group"], Field(description="Discriminator indicating this is a repeatable asset group"), - ] + ] = "repeatable_group" asset_group_id: Annotated[ str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')") ] diff --git a/src/adcp/types/generated_poc/core/format_id.py b/src/adcp/types/generated_poc/core/format_id.py index e3a545dc..f1b8c23b 100644 --- a/src/adcp/types/generated_poc/core/format_id.py +++ b/src/adcp/types/generated_poc/core/format_id.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/format_id.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/frequency_cap.py b/src/adcp/types/generated_poc/core/frequency_cap.py index 29271f77..c411da69 100644 --- a/src/adcp/types/generated_poc/core/frequency_cap.py +++ b/src/adcp/types/generated_poc/core/frequency_cap.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/frequency_cap.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/generation_credential.py b/src/adcp/types/generated_poc/core/generation_credential.py index b47f864d..68ddd108 100644 --- a/src/adcp/types/generated_poc/core/generation_credential.py +++ b/src/adcp/types/generated_poc/core/generation_credential.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/generation_credential.json -# timestamp: 2026-04-18T20:45:21+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/geo_breakdown_support.py b/src/adcp/types/generated_poc/core/geo_breakdown_support.py index 5587b82f..388a8753 100644 --- a/src/adcp/types/generated_poc/core/geo_breakdown_support.py +++ b/src/adcp/types/generated_poc/core/geo_breakdown_support.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/geo_breakdown_support.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/hotel_item.py b/src/adcp/types/generated_poc/core/hotel_item.py index 1bc042f4..3bb58c75 100644 --- a/src/adcp/types/generated_poc/core/hotel_item.py +++ b/src/adcp/types/generated_poc/core/hotel_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/hotel_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/identifier.py b/src/adcp/types/generated_poc/core/identifier.py index e2ab3ed2..214c4349 100644 --- a/src/adcp/types/generated_poc/core/identifier.py +++ b/src/adcp/types/generated_poc/core/identifier.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/identifier.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/industry_identifier.py b/src/adcp/types/generated_poc/core/industry_identifier.py index 1d6e510d..4df14ed2 100644 --- a/src/adcp/types/generated_poc/core/industry_identifier.py +++ b/src/adcp/types/generated_poc/core/industry_identifier.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/industry_identifier.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/insertion_order.py b/src/adcp/types/generated_poc/core/insertion_order.py index 3754f1db..a3e74634 100644 --- a/src/adcp/types/generated_poc/core/insertion_order.py +++ b/src/adcp/types/generated_poc/core/insertion_order.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/insertion_order.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/installment.py b/src/adcp/types/generated_poc/core/installment.py index ad766c8d..336d4959 100644 --- a/src/adcp/types/generated_poc/core/installment.py +++ b/src/adcp/types/generated_poc/core/installment.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/installment.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/installment_deadlines.py b/src/adcp/types/generated_poc/core/installment_deadlines.py index adbbf2d3..1bf16395 100644 --- a/src/adcp/types/generated_poc/core/installment_deadlines.py +++ b/src/adcp/types/generated_poc/core/installment_deadlines.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/installment_deadlines.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/job_item.py b/src/adcp/types/generated_poc/core/job_item.py index a95325f6..6922eb67 100644 --- a/src/adcp/types/generated_poc/core/job_item.py +++ b/src/adcp/types/generated_poc/core/job_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/job_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/limited_series.py b/src/adcp/types/generated_poc/core/limited_series.py index 342ea98b..fe3d3127 100644 --- a/src/adcp/types/generated_poc/core/limited_series.py +++ b/src/adcp/types/generated_poc/core/limited_series.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/limited_series.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/material_deadline.py b/src/adcp/types/generated_poc/core/material_deadline.py index 41251d5d..59cb2636 100644 --- a/src/adcp/types/generated_poc/core/material_deadline.py +++ b/src/adcp/types/generated_poc/core/material_deadline.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/material_deadline.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/mcp_webhook_payload.py b/src/adcp/types/generated_poc/core/mcp_webhook_payload.py index c8b6df4d..e0f4badf 100644 --- a/src/adcp/types/generated_poc/core/mcp_webhook_payload.py +++ b/src/adcp/types/generated_poc/core/mcp_webhook_payload.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/mcp_webhook_payload.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/measurement_readiness.py b/src/adcp/types/generated_poc/core/measurement_readiness.py index 7839b9fb..004b7df3 100644 --- a/src/adcp/types/generated_poc/core/measurement_readiness.py +++ b/src/adcp/types/generated_poc/core/measurement_readiness.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/measurement_readiness.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/measurement_terms.py b/src/adcp/types/generated_poc/core/measurement_terms.py index 2d07a2e6..d8e8832e 100644 --- a/src/adcp/types/generated_poc/core/measurement_terms.py +++ b/src/adcp/types/generated_poc/core/measurement_terms.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/measurement_terms.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/measurement_window.py b/src/adcp/types/generated_poc/core/measurement_window.py index cb300753..1a7d1ac5 100644 --- a/src/adcp/types/generated_poc/core/measurement_window.py +++ b/src/adcp/types/generated_poc/core/measurement_window.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/measurement_window.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/media_buy.py b/src/adcp/types/generated_poc/core/media_buy.py index d0de54cb..cf71c930 100644 --- a/src/adcp/types/generated_poc/core/media_buy.py +++ b/src/adcp/types/generated_poc/core/media_buy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/media_buy.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/media_buy_features.py b/src/adcp/types/generated_poc/core/media_buy_features.py index 59aa5245..820fb117 100644 --- a/src/adcp/types/generated_poc/core/media_buy_features.py +++ b/src/adcp/types/generated_poc/core/media_buy_features.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/media_buy_features.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/offering.py b/src/adcp/types/generated_poc/core/offering.py index 463f94ad..c54192cc 100644 --- a/src/adcp/types/generated_poc/core/offering.py +++ b/src/adcp/types/generated_poc/core/offering.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/offering.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/offering_asset_group.py b/src/adcp/types/generated_poc/core/offering_asset_group.py index 547227e0..374e6198 100644 --- a/src/adcp/types/generated_poc/core/offering_asset_group.py +++ b/src/adcp/types/generated_poc/core/offering_asset_group.py @@ -1,13 +1,13 @@ # generated by datamodel-codegen: # filename: core/offering_asset_group.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations -from typing import Annotated +from typing import Any, Annotated from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field +from pydantic import ConfigDict, Field, RootModel from ..enums import asset_content_type from . import ext as ext_1 @@ -27,6 +27,45 @@ ) +class Items( + RootModel[ + text_asset.TextAsset + | image_asset.ImageAsset + | video_asset.VideoAsset + | audio_asset.AudioAsset + | url_asset.UrlAsset + | html_asset.HtmlAsset + | markdown_asset.MarkdownAsset + | vast_asset.VastAsset + | daast_asset.DaastAsset + | css_asset.CssAsset + | javascript_asset.JavascriptAsset + | webhook_asset.WebhookAsset + ] +): + root: Annotated[ + text_asset.TextAsset + | image_asset.ImageAsset + | video_asset.VideoAsset + | audio_asset.AudioAsset + | url_asset.UrlAsset + | html_asset.HtmlAsset + | markdown_asset.MarkdownAsset + | vast_asset.VastAsset + | daast_asset.DaastAsset + | css_asset.CssAsset + | javascript_asset.JavascriptAsset + | webhook_asset.WebhookAsset, + Field(discriminator="asset_type"), + ] + + def __getattr__(self, name: str) -> Any: + """Proxy attribute access to the wrapped type.""" + if name.startswith("_"): + raise AttributeError(name) + return getattr(self.root, name) + + class OfferingAssetGroup(AdCPBaseModel): model_config = ConfigDict( extra="allow", @@ -42,22 +81,9 @@ class OfferingAssetGroup(AdCPBaseModel): Field(description="The content type of all items in this group."), ] items: Annotated[ - list[ - text_asset.TextAsset - | image_asset.ImageAsset - | video_asset.VideoAsset - | audio_asset.AudioAsset - | url_asset.UrlAsset - | html_asset.HtmlAsset - | markdown_asset.MarkdownAsset - | vast_asset.VastAsset - | daast_asset.DaastAsset - | css_asset.CssAsset - | javascript_asset.JavascriptAsset - | webhook_asset.WebhookAsset - ], + list[Items], Field( - description="The assets in this group. Each item should match the structure for the declared asset_type. Note: JSON Schema validation accepts any valid asset structure here; enforcement that items match asset_type is the responsibility of the consuming agent.", + description="The assets in this group. Each item carries an `asset_type` discriminator that selects the matching asset schema. Note: the group-level `asset_type` declares the expected type; individual items must also self-tag so validators can narrow errors.", min_length=1, ), ] diff --git a/src/adcp/types/generated_poc/core/optimization_goal.py b/src/adcp/types/generated_poc/core/optimization_goal.py index 6049fa3a..1c54029a 100644 --- a/src/adcp/types/generated_poc/core/optimization_goal.py +++ b/src/adcp/types/generated_poc/core/optimization_goal.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/optimization_goal.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -85,7 +85,7 @@ class Target(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[ float, Field(description="Target cost per metric unit in the buy currency", gt=0.0) ] @@ -95,7 +95,7 @@ class Target11(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["threshold_rate"] + kind: Literal["threshold_rate"] = "threshold_rate" value: Annotated[ float, Field( @@ -146,7 +146,7 @@ class Target12(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["cost_per"] + kind: Literal["cost_per"] = "cost_per" value: Annotated[float, Field(description="Target cost per event in the buy currency", gt=0.0)] @@ -154,7 +154,7 @@ class Target13(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["per_ad_spend"] + kind: Literal["per_ad_spend"] = "per_ad_spend" value: Annotated[ float, Field(description="Target return ratio (e.g., 4.0 means $4 of value per $1 spent)", gt=0.0), @@ -165,7 +165,7 @@ class Target14(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["maximize_value"] + kind: Literal["maximize_value"] = "maximize_value" class AttributionWindow(AdCPBaseModel): @@ -190,7 +190,7 @@ class OptimizationGoal2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["event"] + kind: Literal["event"] = "event" event_sources: Annotated[ list[EventSource], Field( @@ -223,7 +223,7 @@ class OptimizationGoal1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["metric"] + kind: Literal["metric"] = "metric" metric: Annotated[ Metric, Field( diff --git a/src/adcp/types/generated_poc/core/outcome_measurement.py b/src/adcp/types/generated_poc/core/outcome_measurement.py index 25527e7f..9950682d 100644 --- a/src/adcp/types/generated_poc/core/outcome_measurement.py +++ b/src/adcp/types/generated_poc/core/outcome_measurement.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/outcome_measurement.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/overlay.py b/src/adcp/types/generated_poc/core/overlay.py index a2e4c488..454a09f8 100644 --- a/src/adcp/types/generated_poc/core/overlay.py +++ b/src/adcp/types/generated_poc/core/overlay.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/overlay.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/package.py b/src/adcp/types/generated_poc/core/package.py index b4f75a2c..18664541 100644 --- a/src/adcp/types/generated_poc/core/package.py +++ b/src/adcp/types/generated_poc/core/package.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/package.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/pagination_request.py b/src/adcp/types/generated_poc/core/pagination_request.py index a1255cc4..4e62d3e4 100644 --- a/src/adcp/types/generated_poc/core/pagination_request.py +++ b/src/adcp/types/generated_poc/core/pagination_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/pagination_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/pagination_response.py b/src/adcp/types/generated_poc/core/pagination_response.py index 3d18c1d7..1fc9b559 100644 --- a/src/adcp/types/generated_poc/core/pagination_response.py +++ b/src/adcp/types/generated_poc/core/pagination_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/pagination_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/performance_feedback.py b/src/adcp/types/generated_poc/core/performance_feedback.py index c6e3ce7d..c6b38718 100644 --- a/src/adcp/types/generated_poc/core/performance_feedback.py +++ b/src/adcp/types/generated_poc/core/performance_feedback.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/performance_feedback.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/performance_standard.py b/src/adcp/types/generated_poc/core/performance_standard.py index 75139f89..c4d60ae3 100644 --- a/src/adcp/types/generated_poc/core/performance_standard.py +++ b/src/adcp/types/generated_poc/core/performance_standard.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/performance_standard.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/placement.py b/src/adcp/types/generated_poc/core/placement.py index 8d85ab72..a6525455 100644 --- a/src/adcp/types/generated_poc/core/placement.py +++ b/src/adcp/types/generated_poc/core/placement.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/placement.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/placement_definition.py b/src/adcp/types/generated_poc/core/placement_definition.py index bbe2b422..c8d2ebd6 100644 --- a/src/adcp/types/generated_poc/core/placement_definition.py +++ b/src/adcp/types/generated_poc/core/placement_definition.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/placement_definition.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/planned_delivery.py b/src/adcp/types/generated_poc/core/planned_delivery.py index 0b1f646a..fb2d5670 100644 --- a/src/adcp/types/generated_poc/core/planned_delivery.py +++ b/src/adcp/types/generated_poc/core/planned_delivery.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/planned_delivery.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/price.py b/src/adcp/types/generated_poc/core/price.py index e576d35e..987460e1 100644 --- a/src/adcp/types/generated_poc/core/price.py +++ b/src/adcp/types/generated_poc/core/price.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/price.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/pricing_option.py b/src/adcp/types/generated_poc/core/pricing_option.py index 4b8c88a8..023142bf 100644 --- a/src/adcp/types/generated_poc/core/pricing_option.py +++ b/src/adcp/types/generated_poc/core/pricing_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/pricing_option.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/product.py b/src/adcp/types/generated_poc/core/product.py index 62d8406f..8124960b 100644 --- a/src/adcp/types/generated_poc/core/product.py +++ b/src/adcp/types/generated_poc/core/product.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/product.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/product_allocation.py b/src/adcp/types/generated_poc/core/product_allocation.py index e1f644b6..e586b3bb 100644 --- a/src/adcp/types/generated_poc/core/product_allocation.py +++ b/src/adcp/types/generated_poc/core/product_allocation.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/product_allocation.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/product_filters.py b/src/adcp/types/generated_poc/core/product_filters.py index 081059d1..b06c73b0 100644 --- a/src/adcp/types/generated_poc/core/product_filters.py +++ b/src/adcp/types/generated_poc/core/product_filters.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/product_filters.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/property.py b/src/adcp/types/generated_poc/core/property.py index 018ca04b..7a1346be 100644 --- a/src/adcp/types/generated_poc/core/property.py +++ b/src/adcp/types/generated_poc/core/property.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/property.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/property_id.py b/src/adcp/types/generated_poc/core/property_id.py index b2b31964..44d976f5 100644 --- a/src/adcp/types/generated_poc/core/property_id.py +++ b/src/adcp/types/generated_poc/core/property_id.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/property_id.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/property_list_ref.py b/src/adcp/types/generated_poc/core/property_list_ref.py index a66c92ad..3b61ceff 100644 --- a/src/adcp/types/generated_poc/core/property_list_ref.py +++ b/src/adcp/types/generated_poc/core/property_list_ref.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/property_list_ref.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/property_tag.py b/src/adcp/types/generated_poc/core/property_tag.py index 2dc9564c..1bbcd636 100644 --- a/src/adcp/types/generated_poc/core/property_tag.py +++ b/src/adcp/types/generated_poc/core/property_tag.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/property_tag.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/proposal.py b/src/adcp/types/generated_poc/core/proposal.py index 144d80f0..ec0e518d 100644 --- a/src/adcp/types/generated_poc/core/proposal.py +++ b/src/adcp/types/generated_poc/core/proposal.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/proposal.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/protocol_envelope.py b/src/adcp/types/generated_poc/core/protocol_envelope.py index 2ed08c82..e6e3a02c 100644 --- a/src/adcp/types/generated_poc/core/protocol_envelope.py +++ b/src/adcp/types/generated_poc/core/protocol_envelope.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/protocol_envelope.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/provenance.py b/src/adcp/types/generated_poc/core/provenance.py index 53dd53ca..85b06094 100644 --- a/src/adcp/types/generated_poc/core/provenance.py +++ b/src/adcp/types/generated_poc/core/provenance.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/provenance.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/publisher_property_selector.py b/src/adcp/types/generated_poc/core/publisher_property_selector.py index d4f919bb..d904ccd7 100644 --- a/src/adcp/types/generated_poc/core/publisher_property_selector.py +++ b/src/adcp/types/generated_poc/core/publisher_property_selector.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/publisher_property_selector.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -28,7 +28,7 @@ class PublisherPropertySelector1(AdCPBaseModel): Field( description="Discriminator indicating all properties from this publisher are included" ), - ] + ] = "all" class PublisherPropertySelector2(AdCPBaseModel): @@ -45,7 +45,7 @@ class PublisherPropertySelector2(AdCPBaseModel): selection_type: Annotated[ Literal["by_id"], Field(description="Discriminator indicating selection by specific property IDs"), - ] + ] = "by_id" property_ids: Annotated[ list[property_id.PropertyId], Field(description="Specific property IDs from the publisher's adagents.json", min_length=1), @@ -65,7 +65,7 @@ class PublisherPropertySelector3(AdCPBaseModel): ] selection_type: Annotated[ Literal["by_tag"], Field(description="Discriminator indicating selection by property tags") - ] + ] = "by_tag" property_tags: Annotated[ list[property_tag.PropertyTag], Field( diff --git a/src/adcp/types/generated_poc/core/push_notification_config.py b/src/adcp/types/generated_poc/core/push_notification_config.py index 012bbf3b..905a3ad2 100644 --- a/src/adcp/types/generated_poc/core/push_notification_config.py +++ b/src/adcp/types/generated_poc/core/push_notification_config.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/push_notification_config.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/real_estate_item.py b/src/adcp/types/generated_poc/core/real_estate_item.py index 15082977..724db5fc 100644 --- a/src/adcp/types/generated_poc/core/real_estate_item.py +++ b/src/adcp/types/generated_poc/core/real_estate_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/real_estate_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/reference_asset.py b/src/adcp/types/generated_poc/core/reference_asset.py index e57f054f..5687267a 100644 --- a/src/adcp/types/generated_poc/core/reference_asset.py +++ b/src/adcp/types/generated_poc/core/reference_asset.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/reference_asset.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/reporting_capabilities.py b/src/adcp/types/generated_poc/core/reporting_capabilities.py index e55125d8..e80ac279 100644 --- a/src/adcp/types/generated_poc/core/reporting_capabilities.py +++ b/src/adcp/types/generated_poc/core/reporting_capabilities.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/reporting_capabilities.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/reporting_webhook.py b/src/adcp/types/generated_poc/core/reporting_webhook.py index 0d4a7114..602df503 100644 --- a/src/adcp/types/generated_poc/core/reporting_webhook.py +++ b/src/adcp/types/generated_poc/core/reporting_webhook.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/reporting_webhook.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/asset_requirements.py index 0db67f30..e1d77f7a 100644 --- a/src/adcp/types/generated_poc/core/requirements/asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/asset_requirements.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/audio_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/audio_asset_requirements.py index 6be18be5..b82ff045 100644 --- a/src/adcp/types/generated_poc/core/requirements/audio_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/audio_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/audio_asset_requirements.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/catalog_field_binding.py b/src/adcp/types/generated_poc/core/requirements/catalog_field_binding.py index 2e16b4f5..b3a6f267 100644 --- a/src/adcp/types/generated_poc/core/requirements/catalog_field_binding.py +++ b/src/adcp/types/generated_poc/core/requirements/catalog_field_binding.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/catalog_field_binding.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -16,7 +16,7 @@ class ScalarBinding(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["scalar"] + kind: Literal["scalar"] = "scalar" asset_id: Annotated[ str, Field( @@ -36,7 +36,7 @@ class AssetPoolBinding(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["asset_pool"] + kind: Literal["asset_pool"] = "asset_pool" asset_id: Annotated[ str, Field( @@ -56,7 +56,7 @@ class CatalogFieldBinding1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - kind: Literal["catalog_group"] + kind: Literal["catalog_group"] = "catalog_group" format_group_id: Annotated[ str, Field(description="The asset_group_id of a repeatable_group in the format's assets array."), diff --git a/src/adcp/types/generated_poc/core/requirements/catalog_requirements.py b/src/adcp/types/generated_poc/core/requirements/catalog_requirements.py index 28d093e5..e96cdc81 100644 --- a/src/adcp/types/generated_poc/core/requirements/catalog_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/catalog_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/catalog_requirements.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/css_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/css_asset_requirements.py index afad9dfc..bb6105ed 100644 --- a/src/adcp/types/generated_poc/core/requirements/css_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/css_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/css_asset_requirements.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/daast_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/daast_asset_requirements.py index 64a11446..ce9268d4 100644 --- a/src/adcp/types/generated_poc/core/requirements/daast_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/daast_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/daast_asset_requirements.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/html_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/html_asset_requirements.py index 280f2c98..386545cb 100644 --- a/src/adcp/types/generated_poc/core/requirements/html_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/html_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/html_asset_requirements.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/image_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/image_asset_requirements.py index fd7ba261..5c98a211 100644 --- a/src/adcp/types/generated_poc/core/requirements/image_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/image_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/image_asset_requirements.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/javascript_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/javascript_asset_requirements.py index e7330cb1..5ee4219c 100644 --- a/src/adcp/types/generated_poc/core/requirements/javascript_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/javascript_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/javascript_asset_requirements.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/markdown_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/markdown_asset_requirements.py index 027e8e5f..b6d10832 100644 --- a/src/adcp/types/generated_poc/core/requirements/markdown_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/markdown_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/markdown_asset_requirements.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/offering_asset_constraint.py b/src/adcp/types/generated_poc/core/requirements/offering_asset_constraint.py index 65392e4b..e9c766c0 100644 --- a/src/adcp/types/generated_poc/core/requirements/offering_asset_constraint.py +++ b/src/adcp/types/generated_poc/core/requirements/offering_asset_constraint.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/offering_asset_constraint.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/text_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/text_asset_requirements.py index 8bfb735e..d7212753 100644 --- a/src/adcp/types/generated_poc/core/requirements/text_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/text_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/text_asset_requirements.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/url_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/url_asset_requirements.py index 2874714d..56164988 100644 --- a/src/adcp/types/generated_poc/core/requirements/url_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/url_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/url_asset_requirements.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/vast_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/vast_asset_requirements.py index ed1dee05..6b2a6250 100644 --- a/src/adcp/types/generated_poc/core/requirements/vast_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/vast_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/vast_asset_requirements.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/video_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/video_asset_requirements.py index ccf9187d..d3cebb1e 100644 --- a/src/adcp/types/generated_poc/core/requirements/video_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/video_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/video_asset_requirements.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/requirements/webhook_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/webhook_asset_requirements.py index 05b848ae..93e41a9b 100644 --- a/src/adcp/types/generated_poc/core/requirements/webhook_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/webhook_asset_requirements.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/requirements/webhook_asset_requirements.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/response.py b/src/adcp/types/generated_poc/core/response.py index 1d90a016..97b3d111 100644 --- a/src/adcp/types/generated_poc/core/response.py +++ b/src/adcp/types/generated_poc/core/response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/rights_constraint.py b/src/adcp/types/generated_poc/core/rights_constraint.py index e00e30ff..c79dc0ee 100644 --- a/src/adcp/types/generated_poc/core/rights_constraint.py +++ b/src/adcp/types/generated_poc/core/rights_constraint.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/rights_constraint.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/signal_definition.py b/src/adcp/types/generated_poc/core/signal_definition.py index e7aeb6c8..521b54e7 100644 --- a/src/adcp/types/generated_poc/core/signal_definition.py +++ b/src/adcp/types/generated_poc/core/signal_definition.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/signal_definition.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/signal_filters.py b/src/adcp/types/generated_poc/core/signal_filters.py index da4df5f2..5003afae 100644 --- a/src/adcp/types/generated_poc/core/signal_filters.py +++ b/src/adcp/types/generated_poc/core/signal_filters.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/signal_filters.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/signal_id.py b/src/adcp/types/generated_poc/core/signal_id.py index 1e0bef6b..d5184df6 100644 --- a/src/adcp/types/generated_poc/core/signal_id.py +++ b/src/adcp/types/generated_poc/core/signal_id.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/signal_id.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -19,7 +19,7 @@ class SignalId17(AdCPBaseModel): Field( description="Discriminator indicating this signal is from a data provider's published catalog" ), - ] + ] = "catalog" data_provider_domain: Annotated[ str, Field( @@ -45,7 +45,7 @@ class SignalId18(AdCPBaseModel): Field( description="Discriminator indicating this signal is native to the agent (not from a data provider catalog)" ), - ] + ] = "agent" agent_url: Annotated[ AnyUrl, Field( diff --git a/src/adcp/types/generated_poc/core/signal_pricing.py b/src/adcp/types/generated_poc/core/signal_pricing.py index 492081c6..08a84090 100644 --- a/src/adcp/types/generated_poc/core/signal_pricing.py +++ b/src/adcp/types/generated_poc/core/signal_pricing.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/signal_pricing.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -17,7 +17,7 @@ class VendorPricing1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: ext_1.ExtensionObject | None = None @@ -27,7 +27,7 @@ class VendorPricing2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -56,7 +56,7 @@ class VendorPricing3(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -67,7 +67,7 @@ class VendorPricing4(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -96,7 +96,7 @@ class VendorPricing5(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/core/signal_pricing_option.py b/src/adcp/types/generated_poc/core/signal_pricing_option.py index 8d09b9ce..8e149c25 100644 --- a/src/adcp/types/generated_poc/core/signal_pricing_option.py +++ b/src/adcp/types/generated_poc/core/signal_pricing_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/signal_pricing_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/signal_targeting.py b/src/adcp/types/generated_poc/core/signal_targeting.py index d3d6a19f..56a78a81 100644 --- a/src/adcp/types/generated_poc/core/signal_targeting.py +++ b/src/adcp/types/generated_poc/core/signal_targeting.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/signal_targeting.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -17,7 +17,9 @@ class SignalTargeting4(AdCPBaseModel): extra="allow", ) signal_id: Annotated[signal_id_1.SignalId, Field(description="The signal to target")] - value_type: Annotated[Literal["binary"], Field(description="Discriminator for binary signals")] + value_type: Annotated[ + Literal["binary"], Field(description="Discriminator for binary signals") + ] = "binary" value: Annotated[ bool, Field( @@ -33,7 +35,7 @@ class SignalTargeting5(AdCPBaseModel): signal_id: Annotated[signal_id_1.SignalId, Field(description="The signal to target")] value_type: Annotated[ Literal["categorical"], Field(description="Discriminator for categorical signals") - ] + ] = "categorical" values: Annotated[ list[str], Field( @@ -50,7 +52,7 @@ class SignalTargeting6(AdCPBaseModel): signal_id: Annotated[signal_id_1.SignalId, Field(description="The signal to target")] value_type: Annotated[ Literal["numeric"], Field(description="Discriminator for numeric signals") - ] + ] = "numeric" min_value: Annotated[ float | None, Field( diff --git a/src/adcp/types/generated_poc/core/special.py b/src/adcp/types/generated_poc/core/special.py index 79fefd60..bafdb9c2 100644 --- a/src/adcp/types/generated_poc/core/special.py +++ b/src/adcp/types/generated_poc/core/special.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/special.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/start_timing.py b/src/adcp/types/generated_poc/core/start_timing.py index 1b3dc403..336b4671 100644 --- a/src/adcp/types/generated_poc/core/start_timing.py +++ b/src/adcp/types/generated_poc/core/start_timing.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/start_timing.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/store_item.py b/src/adcp/types/generated_poc/core/store_item.py index fe087401..7fa10d4e 100644 --- a/src/adcp/types/generated_poc/core/store_item.py +++ b/src/adcp/types/generated_poc/core/store_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/store_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/talent.py b/src/adcp/types/generated_poc/core/talent.py index 634709c8..85bfdce5 100644 --- a/src/adcp/types/generated_poc/core/talent.py +++ b/src/adcp/types/generated_poc/core/talent.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/talent.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/targeting.py b/src/adcp/types/generated_poc/core/targeting.py index 6d74c5e1..90aee851 100644 --- a/src/adcp/types/generated_poc/core/targeting.py +++ b/src/adcp/types/generated_poc/core/targeting.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/targeting.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/tasks_get_request.py b/src/adcp/types/generated_poc/core/tasks_get_request.py index ee5d2e82..59e42010 100644 --- a/src/adcp/types/generated_poc/core/tasks_get_request.py +++ b/src/adcp/types/generated_poc/core/tasks_get_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/tasks_get_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/tasks_get_response.py b/src/adcp/types/generated_poc/core/tasks_get_response.py index 90b6f8d5..25b2074f 100644 --- a/src/adcp/types/generated_poc/core/tasks_get_response.py +++ b/src/adcp/types/generated_poc/core/tasks_get_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/tasks_get_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/tasks_list_request.py b/src/adcp/types/generated_poc/core/tasks_list_request.py index ea1a8fb7..5e0dd76c 100644 --- a/src/adcp/types/generated_poc/core/tasks_list_request.py +++ b/src/adcp/types/generated_poc/core/tasks_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/tasks_list_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/tasks_list_response.py b/src/adcp/types/generated_poc/core/tasks_list_response.py index eeab182b..097df501 100644 --- a/src/adcp/types/generated_poc/core/tasks_list_response.py +++ b/src/adcp/types/generated_poc/core/tasks_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/tasks_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/user_match.py b/src/adcp/types/generated_poc/core/user_match.py index 45134651..18f2bbb3 100644 --- a/src/adcp/types/generated_poc/core/user_match.py +++ b/src/adcp/types/generated_poc/core/user_match.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/user_match.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/vehicle_item.py b/src/adcp/types/generated_poc/core/vehicle_item.py index 4df23fbc..65a80826 100644 --- a/src/adcp/types/generated_poc/core/vehicle_item.py +++ b/src/adcp/types/generated_poc/core/vehicle_item.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/vehicle_item.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/core/vendor_pricing_option.py b/src/adcp/types/generated_poc/core/vendor_pricing_option.py index 57d5a56f..55e3a2be 100644 --- a/src/adcp/types/generated_poc/core/vendor_pricing_option.py +++ b/src/adcp/types/generated_poc/core/vendor_pricing_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/vendor_pricing_option.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -17,7 +17,7 @@ class VendorPricingOption1(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["cpm"] + model: Literal["cpm"] = "cpm" cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] ext: ext_1.ExtensionObject | None = None @@ -27,7 +27,7 @@ class VendorPricingOption2(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["percent_of_media"] + model: Literal["percent_of_media"] = "percent_of_media" percent: Annotated[ float, Field(description="Percentage of media spend, e.g. 15 = 15%", ge=0.0, le=100.0) ] @@ -56,7 +56,7 @@ class VendorPricingOption3(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["flat_fee"] + model: Literal["flat_fee"] = "flat_fee" amount: Annotated[float, Field(description="Fixed charge for the billing period", ge=0.0)] period: Annotated[Period, Field(description="Billing period for the flat fee.")] currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] @@ -67,7 +67,7 @@ class VendorPricingOption4(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["per_unit"] + model: Literal["per_unit"] = "per_unit" unit: Annotated[ str, Field( @@ -96,7 +96,7 @@ class VendorPricingOption5(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - model: Literal["custom"] + model: Literal["custom"] = "custom" description: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/core/x_entity_types.py b/src/adcp/types/generated_poc/core/x_entity_types.py index 4210d76d..6777ff65 100644 --- a/src/adcp/types/generated_poc/core/x_entity_types.py +++ b/src/adcp/types/generated_poc/core/x_entity_types.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/x_entity_types.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/creative_feature_result.py b/src/adcp/types/generated_poc/creative/creative_feature_result.py index 4e841d0f..ac2d3553 100644 --- a/src/adcp/types/generated_poc/creative/creative_feature_result.py +++ b/src/adcp/types/generated_poc/creative/creative_feature_result.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/creative_feature_result.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/get_creative_delivery_request.py b/src/adcp/types/generated_poc/creative/get_creative_delivery_request.py index f81bf554..0445d3a8 100644 --- a/src/adcp/types/generated_poc/creative/get_creative_delivery_request.py +++ b/src/adcp/types/generated_poc/creative/get_creative_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/get_creative_delivery_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/get_creative_delivery_response.py b/src/adcp/types/generated_poc/creative/get_creative_delivery_response.py index 6765c141..c68256e5 100644 --- a/src/adcp/types/generated_poc/creative/get_creative_delivery_response.py +++ b/src/adcp/types/generated_poc/creative/get_creative_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/get_creative_delivery_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/get_creative_features_request.py b/src/adcp/types/generated_poc/creative/get_creative_features_request.py index 812bee2c..2b5b7702 100644 --- a/src/adcp/types/generated_poc/creative/get_creative_features_request.py +++ b/src/adcp/types/generated_poc/creative/get_creative_features_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/get_creative_features_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/get_creative_features_response.py b/src/adcp/types/generated_poc/creative/get_creative_features_response.py index bfa63397..44c9be88 100644 --- a/src/adcp/types/generated_poc/creative/get_creative_features_response.py +++ b/src/adcp/types/generated_poc/creative/get_creative_features_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/get_creative_features_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/list_creative_formats_request.py b/src/adcp/types/generated_poc/creative/list_creative_formats_request.py index 21049435..0fa2f7b0 100644 --- a/src/adcp/types/generated_poc/creative/list_creative_formats_request.py +++ b/src/adcp/types/generated_poc/creative/list_creative_formats_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/list_creative_formats_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/list_creative_formats_response.py b/src/adcp/types/generated_poc/creative/list_creative_formats_response.py index 664b09cd..8e655826 100644 --- a/src/adcp/types/generated_poc/creative/list_creative_formats_response.py +++ b/src/adcp/types/generated_poc/creative/list_creative_formats_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/list_creative_formats_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/list_creatives_request.py b/src/adcp/types/generated_poc/creative/list_creatives_request.py index 368f9e25..4fc10015 100644 --- a/src/adcp/types/generated_poc/creative/list_creatives_request.py +++ b/src/adcp/types/generated_poc/creative/list_creatives_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/list_creatives_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/list_creatives_response.py b/src/adcp/types/generated_poc/creative/list_creatives_response.py index a95b6206..e9278690 100644 --- a/src/adcp/types/generated_poc/creative/list_creatives_response.py +++ b/src/adcp/types/generated_poc/creative/list_creatives_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/list_creatives_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -167,7 +167,9 @@ class Creative(AdCPBaseModel): | catalog_asset.CatalogAsset, ] | None, - Field(description="Assets for this creative, keyed by asset_id"), + Field( + description="Assets for this creative, keyed by asset_id. Each asset value carries an `asset_type` discriminator that selects the matching asset schema." + ), ] = None tags: Annotated[ list[str] | None, Field(description="User-defined tags for organization and searchability") diff --git a/src/adcp/types/generated_poc/creative/preview_creative_request.py b/src/adcp/types/generated_poc/creative/preview_creative_request.py index 153f9784..84ae0dda 100644 --- a/src/adcp/types/generated_poc/creative/preview_creative_request.py +++ b/src/adcp/types/generated_poc/creative/preview_creative_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/preview_creative_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/preview_creative_response.py b/src/adcp/types/generated_poc/creative/preview_creative_response.py index d2b9bb7c..80b88228 100644 --- a/src/adcp/types/generated_poc/creative/preview_creative_response.py +++ b/src/adcp/types/generated_poc/creative/preview_creative_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/preview_creative_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -55,7 +55,7 @@ class PreviewCreativeResponse1(AdCPBaseModel): response_type: Annotated[ Literal["single"], Field(description="Discriminator indicating this is a single preview response"), - ] + ] = "single" previews: Annotated[ list[Preview], Field( @@ -141,7 +141,7 @@ class PreviewCreativeResponse2(AdCPBaseModel): response_type: Annotated[ Literal["batch"], Field(description="Discriminator indicating this is a batch preview response"), - ] + ] = "batch" results: Annotated[ list[Results | Results1], Field( @@ -168,7 +168,7 @@ class PreviewCreativeResponse3(AdCPBaseModel): response_type: Annotated[ Literal["variant"], Field(description="Discriminator indicating this is a variant preview response"), - ] + ] = "variant" variant_id: Annotated[str, Field(description="Platform-assigned variant identifier")] creative_id: Annotated[ str | None, Field(description="Creative identifier this variant belongs to") diff --git a/src/adcp/types/generated_poc/creative/preview_render.py b/src/adcp/types/generated_poc/creative/preview_render.py index ee7d887e..bf5f7488 100644 --- a/src/adcp/types/generated_poc/creative/preview_render.py +++ b/src/adcp/types/generated_poc/creative/preview_render.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/preview_render.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -42,7 +42,7 @@ class PreviewRender1(AdCPBaseModel): ] output_format: Annotated[ Literal["url"], Field(description="Discriminator indicating preview_url is provided") - ] + ] = "url" preview_url: Annotated[ AnyUrl, Field( @@ -73,7 +73,7 @@ class PreviewRender2(AdCPBaseModel): ] output_format: Annotated[ Literal["html"], Field(description="Discriminator indicating preview_html is provided") - ] + ] = "html" preview_html: Annotated[ str, Field( @@ -106,7 +106,7 @@ class PreviewRender3(AdCPBaseModel): Field( description="Discriminator indicating both preview_url and preview_html are provided" ), - ] + ] = "both" preview_url: Annotated[ AnyUrl, Field( diff --git a/src/adcp/types/generated_poc/creative/sync_creatives_async_response_input_required.py b/src/adcp/types/generated_poc/creative/sync_creatives_async_response_input_required.py index 45692c73..34baae21 100644 --- a/src/adcp/types/generated_poc/creative/sync_creatives_async_response_input_required.py +++ b/src/adcp/types/generated_poc/creative/sync_creatives_async_response_input_required.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/sync_creatives_async_response_input_required.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/sync_creatives_async_response_submitted.py b/src/adcp/types/generated_poc/creative/sync_creatives_async_response_submitted.py index 02a3b3d2..6ce922ea 100644 --- a/src/adcp/types/generated_poc/creative/sync_creatives_async_response_submitted.py +++ b/src/adcp/types/generated_poc/creative/sync_creatives_async_response_submitted.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/sync_creatives_async_response_submitted.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/sync_creatives_async_response_working.py b/src/adcp/types/generated_poc/creative/sync_creatives_async_response_working.py index f5b46c30..733e38f5 100644 --- a/src/adcp/types/generated_poc/creative/sync_creatives_async_response_working.py +++ b/src/adcp/types/generated_poc/creative/sync_creatives_async_response_working.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/sync_creatives_async_response_working.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/sync_creatives_request.py b/src/adcp/types/generated_poc/creative/sync_creatives_request.py index b0291230..cd86baed 100644 --- a/src/adcp/types/generated_poc/creative/sync_creatives_request.py +++ b/src/adcp/types/generated_poc/creative/sync_creatives_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/sync_creatives_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/creative/sync_creatives_response.py b/src/adcp/types/generated_poc/creative/sync_creatives_response.py index a21ba8e0..d8d0563e 100644 --- a/src/adcp/types/generated_poc/creative/sync_creatives_response.py +++ b/src/adcp/types/generated_poc/creative/sync_creatives_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/sync_creatives_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -40,7 +40,7 @@ class SyncCreativesResponse3(AdCPBaseModel): Field( description="Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose creatives array carries per-item approval state via CreativeStatus. See task-status.json for the full task-status enum." ), - ] + ] = "submitted" task_id: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/enums/account_status.py b/src/adcp/types/generated_poc/enums/account_status.py index 9a6b728b..2f87b477 100644 --- a/src/adcp/types/generated_poc/enums/account_status.py +++ b/src/adcp/types/generated_poc/enums/account_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/account_status.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/action_source.py b/src/adcp/types/generated_poc/enums/action_source.py index d07687e3..76684c12 100644 --- a/src/adcp/types/generated_poc/enums/action_source.py +++ b/src/adcp/types/generated_poc/enums/action_source.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/action_source.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/adcp_protocol.py b/src/adcp/types/generated_poc/enums/adcp_protocol.py index 9fc5dc72..65165420 100644 --- a/src/adcp/types/generated_poc/enums/adcp_protocol.py +++ b/src/adcp/types/generated_poc/enums/adcp_protocol.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/adcp_protocol.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/adjustment_kind.py b/src/adcp/types/generated_poc/enums/adjustment_kind.py index 84226a09..9022109c 100644 --- a/src/adcp/types/generated_poc/enums/adjustment_kind.py +++ b/src/adcp/types/generated_poc/enums/adjustment_kind.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/adjustment_kind.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/advertiser_industry.py b/src/adcp/types/generated_poc/enums/advertiser_industry.py index 2d0f7dc6..8a8de9c1 100644 --- a/src/adcp/types/generated_poc/enums/advertiser_industry.py +++ b/src/adcp/types/generated_poc/enums/advertiser_industry.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/advertiser_industry.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/age_verification_method.py b/src/adcp/types/generated_poc/enums/age_verification_method.py index e662d3ae..e32c0281 100644 --- a/src/adcp/types/generated_poc/enums/age_verification_method.py +++ b/src/adcp/types/generated_poc/enums/age_verification_method.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/age_verification_method.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/assessment_status.py b/src/adcp/types/generated_poc/enums/assessment_status.py index d4038780..d5f587a3 100644 --- a/src/adcp/types/generated_poc/enums/assessment_status.py +++ b/src/adcp/types/generated_poc/enums/assessment_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/assessment_status.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/asset_content_type.py b/src/adcp/types/generated_poc/enums/asset_content_type.py index fc550084..e272418b 100644 --- a/src/adcp/types/generated_poc/enums/asset_content_type.py +++ b/src/adcp/types/generated_poc/enums/asset_content_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/asset_content_type.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/attribution_model.py b/src/adcp/types/generated_poc/enums/attribution_model.py index fbacf086..9e156e1b 100644 --- a/src/adcp/types/generated_poc/enums/attribution_model.py +++ b/src/adcp/types/generated_poc/enums/attribution_model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/attribution_model.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/audience_source.py b/src/adcp/types/generated_poc/enums/audience_source.py index 5308c617..0b5ed7f4 100644 --- a/src/adcp/types/generated_poc/enums/audience_source.py +++ b/src/adcp/types/generated_poc/enums/audience_source.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/audience_source.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/auth_scheme.py b/src/adcp/types/generated_poc/enums/auth_scheme.py index d00e3d10..aac448fb 100644 --- a/src/adcp/types/generated_poc/enums/auth_scheme.py +++ b/src/adcp/types/generated_poc/enums/auth_scheme.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/auth_scheme.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/available_metric.py b/src/adcp/types/generated_poc/enums/available_metric.py index 87989e11..1e3c14fb 100644 --- a/src/adcp/types/generated_poc/enums/available_metric.py +++ b/src/adcp/types/generated_poc/enums/available_metric.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/available_metric.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/brand_agent_type.py b/src/adcp/types/generated_poc/enums/brand_agent_type.py index 5022ab37..7aa524e2 100644 --- a/src/adcp/types/generated_poc/enums/brand_agent_type.py +++ b/src/adcp/types/generated_poc/enums/brand_agent_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/brand_agent_type.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/canceled_by.py b/src/adcp/types/generated_poc/enums/canceled_by.py index a3a1f316..458b5266 100644 --- a/src/adcp/types/generated_poc/enums/canceled_by.py +++ b/src/adcp/types/generated_poc/enums/canceled_by.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/canceled_by.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/catalog_action.py b/src/adcp/types/generated_poc/enums/catalog_action.py index f5715054..bd874316 100644 --- a/src/adcp/types/generated_poc/enums/catalog_action.py +++ b/src/adcp/types/generated_poc/enums/catalog_action.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/catalog_action.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/catalog_item_status.py b/src/adcp/types/generated_poc/enums/catalog_item_status.py index fae12d12..e2781ae9 100644 --- a/src/adcp/types/generated_poc/enums/catalog_item_status.py +++ b/src/adcp/types/generated_poc/enums/catalog_item_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/catalog_item_status.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/catalog_type.py b/src/adcp/types/generated_poc/enums/catalog_type.py index 8ba68338..bf06c8f8 100644 --- a/src/adcp/types/generated_poc/enums/catalog_type.py +++ b/src/adcp/types/generated_poc/enums/catalog_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/catalog_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/channels.py b/src/adcp/types/generated_poc/enums/channels.py index 9094c035..f13aa96c 100644 --- a/src/adcp/types/generated_poc/enums/channels.py +++ b/src/adcp/types/generated_poc/enums/channels.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/channels.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/cloud_storage_protocol.py b/src/adcp/types/generated_poc/enums/cloud_storage_protocol.py index ed4017b9..2bb6ce73 100644 --- a/src/adcp/types/generated_poc/enums/cloud_storage_protocol.py +++ b/src/adcp/types/generated_poc/enums/cloud_storage_protocol.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/cloud_storage_protocol.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/co_branding_requirement.py b/src/adcp/types/generated_poc/enums/co_branding_requirement.py index 70f5a7bd..cfd7e85e 100644 --- a/src/adcp/types/generated_poc/enums/co_branding_requirement.py +++ b/src/adcp/types/generated_poc/enums/co_branding_requirement.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/co_branding_requirement.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/collection_cadence.py b/src/adcp/types/generated_poc/enums/collection_cadence.py index eeea5bbe..68d7055e 100644 --- a/src/adcp/types/generated_poc/enums/collection_cadence.py +++ b/src/adcp/types/generated_poc/enums/collection_cadence.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/collection_cadence.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/collection_relationship.py b/src/adcp/types/generated_poc/enums/collection_relationship.py index 7da67349..744ecb3b 100644 --- a/src/adcp/types/generated_poc/enums/collection_relationship.py +++ b/src/adcp/types/generated_poc/enums/collection_relationship.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/collection_relationship.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/collection_status.py b/src/adcp/types/generated_poc/enums/collection_status.py index 74e0151c..449771e6 100644 --- a/src/adcp/types/generated_poc/enums/collection_status.py +++ b/src/adcp/types/generated_poc/enums/collection_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/collection_status.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/consent_basis.py b/src/adcp/types/generated_poc/enums/consent_basis.py index e967d19d..102dea56 100644 --- a/src/adcp/types/generated_poc/enums/consent_basis.py +++ b/src/adcp/types/generated_poc/enums/consent_basis.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/consent_basis.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/content_id_type.py b/src/adcp/types/generated_poc/enums/content_id_type.py index 39ac3fb8..08d31215 100644 --- a/src/adcp/types/generated_poc/enums/content_id_type.py +++ b/src/adcp/types/generated_poc/enums/content_id_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/content_id_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/content_rating_system.py b/src/adcp/types/generated_poc/enums/content_rating_system.py index de6c83b0..4df6ca52 100644 --- a/src/adcp/types/generated_poc/enums/content_rating_system.py +++ b/src/adcp/types/generated_poc/enums/content_rating_system.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/content_rating_system.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/creative_action.py b/src/adcp/types/generated_poc/enums/creative_action.py index c3951090..8ee3047e 100644 --- a/src/adcp/types/generated_poc/enums/creative_action.py +++ b/src/adcp/types/generated_poc/enums/creative_action.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/creative_action.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/creative_agent_capability.py b/src/adcp/types/generated_poc/enums/creative_agent_capability.py index dd6296b5..3d18e05f 100644 --- a/src/adcp/types/generated_poc/enums/creative_agent_capability.py +++ b/src/adcp/types/generated_poc/enums/creative_agent_capability.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/creative_agent_capability.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/creative_approval_status.py b/src/adcp/types/generated_poc/enums/creative_approval_status.py index 759ab22c..69ba76d4 100644 --- a/src/adcp/types/generated_poc/enums/creative_approval_status.py +++ b/src/adcp/types/generated_poc/enums/creative_approval_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/creative_approval_status.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/creative_identifier_type.py b/src/adcp/types/generated_poc/enums/creative_identifier_type.py index 2a76d707..1d869a08 100644 --- a/src/adcp/types/generated_poc/enums/creative_identifier_type.py +++ b/src/adcp/types/generated_poc/enums/creative_identifier_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/creative_identifier_type.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/creative_quality.py b/src/adcp/types/generated_poc/enums/creative_quality.py index 49599274..adf4aa28 100644 --- a/src/adcp/types/generated_poc/enums/creative_quality.py +++ b/src/adcp/types/generated_poc/enums/creative_quality.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/creative_quality.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/creative_sort_field.py b/src/adcp/types/generated_poc/enums/creative_sort_field.py index 2c1233e4..844bec27 100644 --- a/src/adcp/types/generated_poc/enums/creative_sort_field.py +++ b/src/adcp/types/generated_poc/enums/creative_sort_field.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/creative_sort_field.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/creative_status.py b/src/adcp/types/generated_poc/enums/creative_status.py index c3f3d160..e07ad4a7 100644 --- a/src/adcp/types/generated_poc/enums/creative_status.py +++ b/src/adcp/types/generated_poc/enums/creative_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/creative_status.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/daast_tracking_event.py b/src/adcp/types/generated_poc/enums/daast_tracking_event.py index aa0b5647..a9f3a411 100644 --- a/src/adcp/types/generated_poc/enums/daast_tracking_event.py +++ b/src/adcp/types/generated_poc/enums/daast_tracking_event.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/daast_tracking_event.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/daast_version.py b/src/adcp/types/generated_poc/enums/daast_version.py index 94ff7ceb..b40aa4e4 100644 --- a/src/adcp/types/generated_poc/enums/daast_version.py +++ b/src/adcp/types/generated_poc/enums/daast_version.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/daast_version.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/day_of_week.py b/src/adcp/types/generated_poc/enums/day_of_week.py index 5c520a2e..ddb04245 100644 --- a/src/adcp/types/generated_poc/enums/day_of_week.py +++ b/src/adcp/types/generated_poc/enums/day_of_week.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/day_of_week.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/delegation_authority.py b/src/adcp/types/generated_poc/enums/delegation_authority.py index a343d24a..0adfaefe 100644 --- a/src/adcp/types/generated_poc/enums/delegation_authority.py +++ b/src/adcp/types/generated_poc/enums/delegation_authority.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/delegation_authority.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/delivery_type.py b/src/adcp/types/generated_poc/enums/delivery_type.py index aa8cecf6..8633ed4d 100644 --- a/src/adcp/types/generated_poc/enums/delivery_type.py +++ b/src/adcp/types/generated_poc/enums/delivery_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/delivery_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/demographic_system.py b/src/adcp/types/generated_poc/enums/demographic_system.py index 8d1c05a4..82de4fac 100644 --- a/src/adcp/types/generated_poc/enums/demographic_system.py +++ b/src/adcp/types/generated_poc/enums/demographic_system.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/demographic_system.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/derivative_type.py b/src/adcp/types/generated_poc/enums/derivative_type.py index 3e3969a2..e1826926 100644 --- a/src/adcp/types/generated_poc/enums/derivative_type.py +++ b/src/adcp/types/generated_poc/enums/derivative_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/derivative_type.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/device_platform.py b/src/adcp/types/generated_poc/enums/device_platform.py index 41a9681e..fac6b0ef 100644 --- a/src/adcp/types/generated_poc/enums/device_platform.py +++ b/src/adcp/types/generated_poc/enums/device_platform.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/device_platform.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/device_type.py b/src/adcp/types/generated_poc/enums/device_type.py index 1d30445b..536b3620 100644 --- a/src/adcp/types/generated_poc/enums/device_type.py +++ b/src/adcp/types/generated_poc/enums/device_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/device_type.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/digital_source_type.py b/src/adcp/types/generated_poc/enums/digital_source_type.py index 98a6726b..2b75fe49 100644 --- a/src/adcp/types/generated_poc/enums/digital_source_type.py +++ b/src/adcp/types/generated_poc/enums/digital_source_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/digital_source_type.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/dimension_unit.py b/src/adcp/types/generated_poc/enums/dimension_unit.py index 7ce62280..c5cf6410 100644 --- a/src/adcp/types/generated_poc/enums/dimension_unit.py +++ b/src/adcp/types/generated_poc/enums/dimension_unit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/dimension_unit.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/disclosure_persistence.py b/src/adcp/types/generated_poc/enums/disclosure_persistence.py index e2909874..3a5d7a80 100644 --- a/src/adcp/types/generated_poc/enums/disclosure_persistence.py +++ b/src/adcp/types/generated_poc/enums/disclosure_persistence.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/disclosure_persistence.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/disclosure_position.py b/src/adcp/types/generated_poc/enums/disclosure_position.py index 1afaa4cd..3c625be5 100644 --- a/src/adcp/types/generated_poc/enums/disclosure_position.py +++ b/src/adcp/types/generated_poc/enums/disclosure_position.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/disclosure_position.json -# timestamp: 2026-02-28T17:39:50+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/distance_unit.py b/src/adcp/types/generated_poc/enums/distance_unit.py index e7da9e12..2c7214ce 100644 --- a/src/adcp/types/generated_poc/enums/distance_unit.py +++ b/src/adcp/types/generated_poc/enums/distance_unit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/distance_unit.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/distribution_identifier_type.py b/src/adcp/types/generated_poc/enums/distribution_identifier_type.py index 69f32170..875b6b73 100644 --- a/src/adcp/types/generated_poc/enums/distribution_identifier_type.py +++ b/src/adcp/types/generated_poc/enums/distribution_identifier_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/distribution_identifier_type.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/error_code.py b/src/adcp/types/generated_poc/enums/error_code.py index 288772dc..1aca29e2 100644 --- a/src/adcp/types/generated_poc/enums/error_code.py +++ b/src/adcp/types/generated_poc/enums/error_code.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/error_code.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/escalation_severity.py b/src/adcp/types/generated_poc/enums/escalation_severity.py index 53b13b83..a5652c31 100644 --- a/src/adcp/types/generated_poc/enums/escalation_severity.py +++ b/src/adcp/types/generated_poc/enums/escalation_severity.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/escalation_severity.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/event_type.py b/src/adcp/types/generated_poc/enums/event_type.py index 82b99cd3..a7865052 100644 --- a/src/adcp/types/generated_poc/enums/event_type.py +++ b/src/adcp/types/generated_poc/enums/event_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/event_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/exclusivity.py b/src/adcp/types/generated_poc/enums/exclusivity.py index b305ca96..cc3546b2 100644 --- a/src/adcp/types/generated_poc/enums/exclusivity.py +++ b/src/adcp/types/generated_poc/enums/exclusivity.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/exclusivity.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/feed_format.py b/src/adcp/types/generated_poc/enums/feed_format.py index ad284ca5..3003d53b 100644 --- a/src/adcp/types/generated_poc/enums/feed_format.py +++ b/src/adcp/types/generated_poc/enums/feed_format.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/feed_format.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/feedback_source.py b/src/adcp/types/generated_poc/enums/feedback_source.py index 8181ac43..1b73e403 100644 --- a/src/adcp/types/generated_poc/enums/feedback_source.py +++ b/src/adcp/types/generated_poc/enums/feedback_source.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/feedback_source.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/forecast_method.py b/src/adcp/types/generated_poc/enums/forecast_method.py index 007f8a5d..de20ee34 100644 --- a/src/adcp/types/generated_poc/enums/forecast_method.py +++ b/src/adcp/types/generated_poc/enums/forecast_method.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/forecast_method.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/forecast_range_unit.py b/src/adcp/types/generated_poc/enums/forecast_range_unit.py index 6d7b8405..d82f15e0 100644 --- a/src/adcp/types/generated_poc/enums/forecast_range_unit.py +++ b/src/adcp/types/generated_poc/enums/forecast_range_unit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/forecast_range_unit.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/forecastable_metric.py b/src/adcp/types/generated_poc/enums/forecastable_metric.py index 1309ec47..8613e4b2 100644 --- a/src/adcp/types/generated_poc/enums/forecastable_metric.py +++ b/src/adcp/types/generated_poc/enums/forecastable_metric.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/forecastable_metric.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/format_id_parameter.py b/src/adcp/types/generated_poc/enums/format_id_parameter.py index 60dee5a8..90cd0634 100644 --- a/src/adcp/types/generated_poc/enums/format_id_parameter.py +++ b/src/adcp/types/generated_poc/enums/format_id_parameter.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/format_id_parameter.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/frequency_cap_scope.py b/src/adcp/types/generated_poc/enums/frequency_cap_scope.py index 1e3de7be..66292315 100644 --- a/src/adcp/types/generated_poc/enums/frequency_cap_scope.py +++ b/src/adcp/types/generated_poc/enums/frequency_cap_scope.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/frequency_cap_scope.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -13,4 +13,4 @@ class FrequencyCapScope(RootModel[Literal["package"]]): root: Annotated[ Literal["package"], Field(description="Scope for frequency cap application", title="Frequency Cap Scope"), - ] + ] = "package" diff --git a/src/adcp/types/generated_poc/enums/genre_taxonomy.py b/src/adcp/types/generated_poc/enums/genre_taxonomy.py index 027764b9..b8fb0a6a 100644 --- a/src/adcp/types/generated_poc/enums/genre_taxonomy.py +++ b/src/adcp/types/generated_poc/enums/genre_taxonomy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/genre_taxonomy.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/geo_level.py b/src/adcp/types/generated_poc/enums/geo_level.py index 50d6797f..de4fed1c 100644 --- a/src/adcp/types/generated_poc/enums/geo_level.py +++ b/src/adcp/types/generated_poc/enums/geo_level.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/geo_level.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/governance_domain.py b/src/adcp/types/generated_poc/enums/governance_domain.py index c1c04a2d..0589e4c3 100644 --- a/src/adcp/types/generated_poc/enums/governance_domain.py +++ b/src/adcp/types/generated_poc/enums/governance_domain.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/governance_domain.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/governance_mode.py b/src/adcp/types/generated_poc/enums/governance_mode.py index 4437cfbf..5693b659 100644 --- a/src/adcp/types/generated_poc/enums/governance_mode.py +++ b/src/adcp/types/generated_poc/enums/governance_mode.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/governance_mode.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/governance_phase.py b/src/adcp/types/generated_poc/enums/governance_phase.py index e12bc2e0..13050272 100644 --- a/src/adcp/types/generated_poc/enums/governance_phase.py +++ b/src/adcp/types/generated_poc/enums/governance_phase.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/governance_phase.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/history_entry_type.py b/src/adcp/types/generated_poc/enums/history_entry_type.py index b80c40f8..fec750f0 100644 --- a/src/adcp/types/generated_poc/enums/history_entry_type.py +++ b/src/adcp/types/generated_poc/enums/history_entry_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/history_entry_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/http_method.py b/src/adcp/types/generated_poc/enums/http_method.py index 725bc47a..b3d56fae 100644 --- a/src/adcp/types/generated_poc/enums/http_method.py +++ b/src/adcp/types/generated_poc/enums/http_method.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/http_method.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/identifier_types.py b/src/adcp/types/generated_poc/enums/identifier_types.py index ff2d86a2..6006aa3f 100644 --- a/src/adcp/types/generated_poc/enums/identifier_types.py +++ b/src/adcp/types/generated_poc/enums/identifier_types.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/identifier_types.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/installment_status.py b/src/adcp/types/generated_poc/enums/installment_status.py index e7e3f10c..22c9f129 100644 --- a/src/adcp/types/generated_poc/enums/installment_status.py +++ b/src/adcp/types/generated_poc/enums/installment_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/installment_status.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/javascript_module_type.py b/src/adcp/types/generated_poc/enums/javascript_module_type.py index 055eacf1..a461540f 100644 --- a/src/adcp/types/generated_poc/enums/javascript_module_type.py +++ b/src/adcp/types/generated_poc/enums/javascript_module_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/javascript_module_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/landing_page_requirement.py b/src/adcp/types/generated_poc/enums/landing_page_requirement.py index 1c538ee8..ec1ca647 100644 --- a/src/adcp/types/generated_poc/enums/landing_page_requirement.py +++ b/src/adcp/types/generated_poc/enums/landing_page_requirement.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/landing_page_requirement.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/makegood_remedy.py b/src/adcp/types/generated_poc/enums/makegood_remedy.py index 0f59fc45..91c24c32 100644 --- a/src/adcp/types/generated_poc/enums/makegood_remedy.py +++ b/src/adcp/types/generated_poc/enums/makegood_remedy.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/makegood_remedy.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/markdown_flavor.py b/src/adcp/types/generated_poc/enums/markdown_flavor.py index 65e9a999..a6c93394 100644 --- a/src/adcp/types/generated_poc/enums/markdown_flavor.py +++ b/src/adcp/types/generated_poc/enums/markdown_flavor.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/markdown_flavor.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/match_id_type.py b/src/adcp/types/generated_poc/enums/match_id_type.py index a595f0e4..7cae33b7 100644 --- a/src/adcp/types/generated_poc/enums/match_id_type.py +++ b/src/adcp/types/generated_poc/enums/match_id_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/match_id_type.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/media_buy_status.py b/src/adcp/types/generated_poc/enums/media_buy_status.py index 5bfcc0f3..91f2df5e 100644 --- a/src/adcp/types/generated_poc/enums/media_buy_status.py +++ b/src/adcp/types/generated_poc/enums/media_buy_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/media_buy_status.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/metric_type.py b/src/adcp/types/generated_poc/enums/metric_type.py index 478f2069..c2804034 100644 --- a/src/adcp/types/generated_poc/enums/metric_type.py +++ b/src/adcp/types/generated_poc/enums/metric_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/metric_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/metro_system.py b/src/adcp/types/generated_poc/enums/metro_system.py index 6651e077..9ab67a91 100644 --- a/src/adcp/types/generated_poc/enums/metro_system.py +++ b/src/adcp/types/generated_poc/enums/metro_system.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/metro_system.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/notification_type.py b/src/adcp/types/generated_poc/enums/notification_type.py index c203d238..ef7592ae 100644 --- a/src/adcp/types/generated_poc/enums/notification_type.py +++ b/src/adcp/types/generated_poc/enums/notification_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/notification_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/outcome_type.py b/src/adcp/types/generated_poc/enums/outcome_type.py index 14f2bcd8..104026a2 100644 --- a/src/adcp/types/generated_poc/enums/outcome_type.py +++ b/src/adcp/types/generated_poc/enums/outcome_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/outcome_type.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/pacing.py b/src/adcp/types/generated_poc/enums/pacing.py index 41ac206e..1e2bfc7c 100644 --- a/src/adcp/types/generated_poc/enums/pacing.py +++ b/src/adcp/types/generated_poc/enums/pacing.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/pacing.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/performance_standard_metric.py b/src/adcp/types/generated_poc/enums/performance_standard_metric.py index 6f018fe8..1e963ff5 100644 --- a/src/adcp/types/generated_poc/enums/performance_standard_metric.py +++ b/src/adcp/types/generated_poc/enums/performance_standard_metric.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/performance_standard_metric.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/policy_category.py b/src/adcp/types/generated_poc/enums/policy_category.py index 5a39718e..21ad6fce 100644 --- a/src/adcp/types/generated_poc/enums/policy_category.py +++ b/src/adcp/types/generated_poc/enums/policy_category.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/policy_category.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/policy_enforcement.py b/src/adcp/types/generated_poc/enums/policy_enforcement.py index 03339f7b..86955bb4 100644 --- a/src/adcp/types/generated_poc/enums/policy_enforcement.py +++ b/src/adcp/types/generated_poc/enums/policy_enforcement.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/policy_enforcement.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/postal_system.py b/src/adcp/types/generated_poc/enums/postal_system.py index b7ee922e..bfec1d52 100644 --- a/src/adcp/types/generated_poc/enums/postal_system.py +++ b/src/adcp/types/generated_poc/enums/postal_system.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/postal_system.json -# timestamp: 2026-02-27T02:10:10+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/preview_output_format.py b/src/adcp/types/generated_poc/enums/preview_output_format.py index a8268220..b6a9abc1 100644 --- a/src/adcp/types/generated_poc/enums/preview_output_format.py +++ b/src/adcp/types/generated_poc/enums/preview_output_format.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/preview_output_format.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/pricing_model.py b/src/adcp/types/generated_poc/enums/pricing_model.py index 3eeb496e..574a25c8 100644 --- a/src/adcp/types/generated_poc/enums/pricing_model.py +++ b/src/adcp/types/generated_poc/enums/pricing_model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/pricing_model.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/production_quality.py b/src/adcp/types/generated_poc/enums/production_quality.py index 630f63a5..b83d590f 100644 --- a/src/adcp/types/generated_poc/enums/production_quality.py +++ b/src/adcp/types/generated_poc/enums/production_quality.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/production_quality.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/property_type.py b/src/adcp/types/generated_poc/enums/property_type.py index 8e82b79c..0c617f74 100644 --- a/src/adcp/types/generated_poc/enums/property_type.py +++ b/src/adcp/types/generated_poc/enums/property_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/property_type.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/proposal_status.py b/src/adcp/types/generated_poc/enums/proposal_status.py index 66591c8d..58274579 100644 --- a/src/adcp/types/generated_poc/enums/proposal_status.py +++ b/src/adcp/types/generated_poc/enums/proposal_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/proposal_status.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/publisher_identifier_types.py b/src/adcp/types/generated_poc/enums/publisher_identifier_types.py index bea011b4..d84c8b3f 100644 --- a/src/adcp/types/generated_poc/enums/publisher_identifier_types.py +++ b/src/adcp/types/generated_poc/enums/publisher_identifier_types.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/publisher_identifier_types.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/purchase_type.py b/src/adcp/types/generated_poc/enums/purchase_type.py index 46403ab9..42f2ecc4 100644 --- a/src/adcp/types/generated_poc/enums/purchase_type.py +++ b/src/adcp/types/generated_poc/enums/purchase_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/purchase_type.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/reach_unit.py b/src/adcp/types/generated_poc/enums/reach_unit.py index 25631711..ed75ece6 100644 --- a/src/adcp/types/generated_poc/enums/reach_unit.py +++ b/src/adcp/types/generated_poc/enums/reach_unit.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/reach_unit.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/reporting_frequency.py b/src/adcp/types/generated_poc/enums/reporting_frequency.py index 5c954539..0d68c421 100644 --- a/src/adcp/types/generated_poc/enums/reporting_frequency.py +++ b/src/adcp/types/generated_poc/enums/reporting_frequency.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/reporting_frequency.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/response_type.py b/src/adcp/types/generated_poc/enums/response_type.py index fc0f31ec..c28da177 100644 --- a/src/adcp/types/generated_poc/enums/response_type.py +++ b/src/adcp/types/generated_poc/enums/response_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/response_type.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/restricted_attribute.py b/src/adcp/types/generated_poc/enums/restricted_attribute.py index 261de242..7fea6f5c 100644 --- a/src/adcp/types/generated_poc/enums/restricted_attribute.py +++ b/src/adcp/types/generated_poc/enums/restricted_attribute.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/restricted_attribute.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/right_type.py b/src/adcp/types/generated_poc/enums/right_type.py index 8ebe8563..808ebcff 100644 --- a/src/adcp/types/generated_poc/enums/right_type.py +++ b/src/adcp/types/generated_poc/enums/right_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/right_type.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/right_use.py b/src/adcp/types/generated_poc/enums/right_use.py index be0b953b..170ecd5e 100644 --- a/src/adcp/types/generated_poc/enums/right_use.py +++ b/src/adcp/types/generated_poc/enums/right_use.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/right_use.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/si_session_status.py b/src/adcp/types/generated_poc/enums/si_session_status.py index 09726228..d284061a 100644 --- a/src/adcp/types/generated_poc/enums/si_session_status.py +++ b/src/adcp/types/generated_poc/enums/si_session_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/si_session_status.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/signal_catalog_type.py b/src/adcp/types/generated_poc/enums/signal_catalog_type.py index 06552f4f..40ac5ed7 100644 --- a/src/adcp/types/generated_poc/enums/signal_catalog_type.py +++ b/src/adcp/types/generated_poc/enums/signal_catalog_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/signal_catalog_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/signal_source.py b/src/adcp/types/generated_poc/enums/signal_source.py index 5e00e065..40225b0e 100644 --- a/src/adcp/types/generated_poc/enums/signal_source.py +++ b/src/adcp/types/generated_poc/enums/signal_source.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/signal_source.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/signal_value_type.py b/src/adcp/types/generated_poc/enums/signal_value_type.py index fe52d8c7..ca6b2754 100644 --- a/src/adcp/types/generated_poc/enums/signal_value_type.py +++ b/src/adcp/types/generated_poc/enums/signal_value_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/signal_value_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/sort_direction.py b/src/adcp/types/generated_poc/enums/sort_direction.py index 27ae0747..c81964e3 100644 --- a/src/adcp/types/generated_poc/enums/sort_direction.py +++ b/src/adcp/types/generated_poc/enums/sort_direction.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/sort_direction.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/sort_metric.py b/src/adcp/types/generated_poc/enums/sort_metric.py index 30bf559f..531761dc 100644 --- a/src/adcp/types/generated_poc/enums/sort_metric.py +++ b/src/adcp/types/generated_poc/enums/sort_metric.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/sort_metric.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/special_category.py b/src/adcp/types/generated_poc/enums/special_category.py index 5ebc1500..17db72a5 100644 --- a/src/adcp/types/generated_poc/enums/special_category.py +++ b/src/adcp/types/generated_poc/enums/special_category.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/special_category.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/specialism.py b/src/adcp/types/generated_poc/enums/specialism.py index 835ae443..9d30896d 100644 --- a/src/adcp/types/generated_poc/enums/specialism.py +++ b/src/adcp/types/generated_poc/enums/specialism.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/specialism.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/talent_role.py b/src/adcp/types/generated_poc/enums/talent_role.py index b8e4bf05..3cf25646 100644 --- a/src/adcp/types/generated_poc/enums/talent_role.py +++ b/src/adcp/types/generated_poc/enums/talent_role.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/talent_role.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/task_status.py b/src/adcp/types/generated_poc/enums/task_status.py index 917f05dc..93e58b61 100644 --- a/src/adcp/types/generated_poc/enums/task_status.py +++ b/src/adcp/types/generated_poc/enums/task_status.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/task_status.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/task_type.py b/src/adcp/types/generated_poc/enums/task_type.py index 07d4111b..2d33d798 100644 --- a/src/adcp/types/generated_poc/enums/task_type.py +++ b/src/adcp/types/generated_poc/enums/task_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/task_type.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/transport_mode.py b/src/adcp/types/generated_poc/enums/transport_mode.py index 2a798863..535a144a 100644 --- a/src/adcp/types/generated_poc/enums/transport_mode.py +++ b/src/adcp/types/generated_poc/enums/transport_mode.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/transport_mode.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/uid_type.py b/src/adcp/types/generated_poc/enums/uid_type.py index a900af09..470a29f2 100644 --- a/src/adcp/types/generated_poc/enums/uid_type.py +++ b/src/adcp/types/generated_poc/enums/uid_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/uid_type.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/universal_macro.py b/src/adcp/types/generated_poc/enums/universal_macro.py index 98e9645e..554cde7a 100644 --- a/src/adcp/types/generated_poc/enums/universal_macro.py +++ b/src/adcp/types/generated_poc/enums/universal_macro.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/universal_macro.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/update_frequency.py b/src/adcp/types/generated_poc/enums/update_frequency.py index e6a0b52e..08ad209c 100644 --- a/src/adcp/types/generated_poc/enums/update_frequency.py +++ b/src/adcp/types/generated_poc/enums/update_frequency.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/update_frequency.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/url_asset_type.py b/src/adcp/types/generated_poc/enums/url_asset_type.py index 3391646f..a0743b5f 100644 --- a/src/adcp/types/generated_poc/enums/url_asset_type.py +++ b/src/adcp/types/generated_poc/enums/url_asset_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/url_asset_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/validation_mode.py b/src/adcp/types/generated_poc/enums/validation_mode.py index 646eeac4..6af9423d 100644 --- a/src/adcp/types/generated_poc/enums/validation_mode.py +++ b/src/adcp/types/generated_poc/enums/validation_mode.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/validation_mode.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/vast_tracking_event.py b/src/adcp/types/generated_poc/enums/vast_tracking_event.py index db656057..fe85cd8e 100644 --- a/src/adcp/types/generated_poc/enums/vast_tracking_event.py +++ b/src/adcp/types/generated_poc/enums/vast_tracking_event.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/vast_tracking_event.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/vast_version.py b/src/adcp/types/generated_poc/enums/vast_version.py index 36b189e0..596c5c52 100644 --- a/src/adcp/types/generated_poc/enums/vast_version.py +++ b/src/adcp/types/generated_poc/enums/vast_version.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/vast_version.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/viewability_standard.py b/src/adcp/types/generated_poc/enums/viewability_standard.py index 77dd4783..2cf6f65a 100644 --- a/src/adcp/types/generated_poc/enums/viewability_standard.py +++ b/src/adcp/types/generated_poc/enums/viewability_standard.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/viewability_standard.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/wcag_level.py b/src/adcp/types/generated_poc/enums/wcag_level.py index 8d8aa217..ff440031 100644 --- a/src/adcp/types/generated_poc/enums/wcag_level.py +++ b/src/adcp/types/generated_poc/enums/wcag_level.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/wcag_level.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/webhook_response_type.py b/src/adcp/types/generated_poc/enums/webhook_response_type.py index bf0edfd5..e9ce0477 100644 --- a/src/adcp/types/generated_poc/enums/webhook_response_type.py +++ b/src/adcp/types/generated_poc/enums/webhook_response_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/webhook_response_type.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/enums/webhook_security_method.py b/src/adcp/types/generated_poc/enums/webhook_security_method.py index fdeeb65d..b2f5310a 100644 --- a/src/adcp/types/generated_poc/enums/webhook_security_method.py +++ b/src/adcp/types/generated_poc/enums/webhook_security_method.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/webhook_security_method.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/account_setup_required.py b/src/adcp/types/generated_poc/error_details/account_setup_required.py index 533b7f02..f0783811 100644 --- a/src/adcp/types/generated_poc/error_details/account_setup_required.py +++ b/src/adcp/types/generated_poc/error_details/account_setup_required.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/account_setup_required.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/audience_too_small.py b/src/adcp/types/generated_poc/error_details/audience_too_small.py index be0d446f..e69c024d 100644 --- a/src/adcp/types/generated_poc/error_details/audience_too_small.py +++ b/src/adcp/types/generated_poc/error_details/audience_too_small.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/audience_too_small.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/budget_too_low.py b/src/adcp/types/generated_poc/error_details/budget_too_low.py index 0e535e27..4f2b422b 100644 --- a/src/adcp/types/generated_poc/error_details/budget_too_low.py +++ b/src/adcp/types/generated_poc/error_details/budget_too_low.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/budget_too_low.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/conflict.py b/src/adcp/types/generated_poc/error_details/conflict.py index 69bf959b..0c64672d 100644 --- a/src/adcp/types/generated_poc/error_details/conflict.py +++ b/src/adcp/types/generated_poc/error_details/conflict.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/conflict.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/creative_rejected.py b/src/adcp/types/generated_poc/error_details/creative_rejected.py index e84e1f17..0fac597e 100644 --- a/src/adcp/types/generated_poc/error_details/creative_rejected.py +++ b/src/adcp/types/generated_poc/error_details/creative_rejected.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/creative_rejected.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/policy_violation.py b/src/adcp/types/generated_poc/error_details/policy_violation.py index 8f61e863..5a3fe8f3 100644 --- a/src/adcp/types/generated_poc/error_details/policy_violation.py +++ b/src/adcp/types/generated_poc/error_details/policy_violation.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/policy_violation.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/rate_limited.py b/src/adcp/types/generated_poc/error_details/rate_limited.py index 38b7ce29..2fea6845 100644 --- a/src/adcp/types/generated_poc/error_details/rate_limited.py +++ b/src/adcp/types/generated_poc/error_details/rate_limited.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/rate_limited.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/error_details/vendor_error_codes.py b/src/adcp/types/generated_poc/error_details/vendor_error_codes.py index bf1a9c0d..9da101c6 100644 --- a/src/adcp/types/generated_poc/error_details/vendor_error_codes.py +++ b/src/adcp/types/generated_poc/error_details/vendor_error_codes.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: error_details/vendor_error_codes.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/extensions/extension_meta.py b/src/adcp/types/generated_poc/extensions/extension_meta.py index 0b565876..b4c60116 100644 --- a/src/adcp/types/generated_poc/extensions/extension_meta.py +++ b/src/adcp/types/generated_poc/extensions/extension_meta.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: extensions/extension_meta.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -13,7 +13,7 @@ class AdcpExtensionFileSchema(AdCPBaseModel): field_schema: Annotated[ Literal["http://json-schema.org/draft-07/schema#"], Field(alias="$schema") - ] + ] = "http://json-schema.org/draft-07/schema#" title: Annotated[str, Field(description="Human-readable title for the extension")] description: Annotated[str, Field(description="Description of what this extension provides")] valid_from: Annotated[ @@ -36,7 +36,7 @@ class AdcpExtensionFileSchema(AdCPBaseModel): type: Annotated[ Literal["object"], Field(description="Extensions must be objects (data within ext.{namespace})"), - ] + ] = "object" properties: Annotated[ dict[str, Any], Field(description="Schema properties defining the structure of ext.{namespace} data"), diff --git a/src/adcp/types/generated_poc/governance/attribute_definition.py b/src/adcp/types/generated_poc/governance/attribute_definition.py index a835daa1..7fd994db 100644 --- a/src/adcp/types/generated_poc/governance/attribute_definition.py +++ b/src/adcp/types/generated_poc/governance/attribute_definition.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/attribute_definition.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/audience_constraints.py b/src/adcp/types/generated_poc/governance/audience_constraints.py index 33808b34..f4735329 100644 --- a/src/adcp/types/generated_poc/governance/audience_constraints.py +++ b/src/adcp/types/generated_poc/governance/audience_constraints.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/audience_constraints.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/check_governance_request.py b/src/adcp/types/generated_poc/governance/check_governance_request.py index 4c651816..08f8a178 100644 --- a/src/adcp/types/generated_poc/governance/check_governance_request.py +++ b/src/adcp/types/generated_poc/governance/check_governance_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/check_governance_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -125,7 +125,12 @@ class CheckGovernanceRequest(AdCPBaseModel): le=99, ), ] = None - plan_id: Annotated[str, Field(description="Campaign governance plan identifier.")] + plan_id: Annotated[ + str, + Field( + description="Campaign governance plan identifier. The plan uniquely scopes the account and operator; do not include a separate `account` field — the governance agent resolves account from the plan. Including `account` is rejected by `additionalProperties: false`." + ), + ] caller: Annotated[AnyUrl, Field(description="URL of the agent making the request.")] purchase_type: Annotated[ purchase_type_1.PurchaseType | None, diff --git a/src/adcp/types/generated_poc/governance/check_governance_response.py b/src/adcp/types/generated_poc/governance/check_governance_response.py index e884ce4c..c38ca9a5 100644 --- a/src/adcp/types/generated_poc/governance/check_governance_response.py +++ b/src/adcp/types/generated_poc/governance/check_governance_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/check_governance_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/get_plan_audit_logs_request.py b/src/adcp/types/generated_poc/governance/get_plan_audit_logs_request.py index b875fc52..15036366 100644 --- a/src/adcp/types/generated_poc/governance/get_plan_audit_logs_request.py +++ b/src/adcp/types/generated_poc/governance/get_plan_audit_logs_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/get_plan_audit_logs_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -29,7 +29,7 @@ class GetPlanAuditLogsRequest(AdCPBaseModel): plan_ids: Annotated[ list[str] | None, Field( - description="Plan IDs to retrieve. For a single plan, pass a one-element array.", + description="Plan IDs to retrieve. For a single plan, pass a one-element array. Plans uniquely scope account and operator; do not include a separate `account` field — the governance agent resolves account from each plan. Including `account` is rejected by `additionalProperties: false`.", min_length=1, ), ] = None diff --git a/src/adcp/types/generated_poc/governance/get_plan_audit_logs_response.py b/src/adcp/types/generated_poc/governance/get_plan_audit_logs_response.py index c40bf296..19525423 100644 --- a/src/adcp/types/generated_poc/governance/get_plan_audit_logs_response.py +++ b/src/adcp/types/generated_poc/governance/get_plan_audit_logs_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/get_plan_audit_logs_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/policy_category_definition.py b/src/adcp/types/generated_poc/governance/policy_category_definition.py index 4bad4051..9b1e0ec6 100644 --- a/src/adcp/types/generated_poc/governance/policy_category_definition.py +++ b/src/adcp/types/generated_poc/governance/policy_category_definition.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/policy_category_definition.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/policy_entry.py b/src/adcp/types/generated_poc/governance/policy_entry.py index cf067746..5be8d647 100644 --- a/src/adcp/types/generated_poc/governance/policy_entry.py +++ b/src/adcp/types/generated_poc/governance/policy_entry.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/policy_entry.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/policy_ref.py b/src/adcp/types/generated_poc/governance/policy_ref.py index b5ceb3cd..707e6d29 100644 --- a/src/adcp/types/generated_poc/governance/policy_ref.py +++ b/src/adcp/types/generated_poc/governance/policy_ref.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/policy_ref.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/report_plan_outcome_request.py b/src/adcp/types/generated_poc/governance/report_plan_outcome_request.py index e09337b9..2b429eea 100644 --- a/src/adcp/types/generated_poc/governance/report_plan_outcome_request.py +++ b/src/adcp/types/generated_poc/governance/report_plan_outcome_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/report_plan_outcome_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -103,7 +103,12 @@ class ReportPlanOutcomeRequest(AdCPBaseModel): le=99, ), ] = None - plan_id: Annotated[str, Field(description="The plan this outcome is for.")] + plan_id: Annotated[ + str, + Field( + description="The plan this outcome is for. The plan uniquely scopes the account and operator; do not include a separate `account` field — the governance agent resolves account from the plan. Including `account` is rejected by `additionalProperties: false`." + ), + ] check_id: Annotated[ str | None, Field( diff --git a/src/adcp/types/generated_poc/governance/report_plan_outcome_response.py b/src/adcp/types/generated_poc/governance/report_plan_outcome_response.py index 802dc64a..e9bca4c7 100644 --- a/src/adcp/types/generated_poc/governance/report_plan_outcome_response.py +++ b/src/adcp/types/generated_poc/governance/report_plan_outcome_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/report_plan_outcome_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/sync_plans_request.py b/src/adcp/types/generated_poc/governance/sync_plans_request.py index 1b8bcc09..d1d21a39 100644 --- a/src/adcp/types/generated_poc/governance/sync_plans_request.py +++ b/src/adcp/types/generated_poc/governance/sync_plans_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/sync_plans_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/governance/sync_plans_response.py b/src/adcp/types/generated_poc/governance/sync_plans_response.py index 92b55205..9cfdef89 100644 --- a/src/adcp/types/generated_poc/governance/sync_plans_response.py +++ b/src/adcp/types/generated_poc/governance/sync_plans_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: governance/sync_plans_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -20,7 +20,7 @@ class Status(Enum): error = "error" -class Status38(Enum): +class Status42(Enum): active = "active" inactive = "inactive" @@ -30,7 +30,7 @@ class Category(AdCPBaseModel): extra="forbid", ) category_id: Annotated[str, Field(description="Validation category identifier.")] - status: Annotated[Status38, Field(description="Whether this category is active for this plan.")] + status: Annotated[Status42, Field(description="Whether this category is active for this plan.")] class Source(Enum): diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/build_creative_async_response_input_required.py index ef2a6501..810e4d7a 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_async_response_input_required.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/build_creative_async_response_input_required.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/build_creative_async_response_submitted.py index 68c1ddc1..1c785e74 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_async_response_submitted.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/build_creative_async_response_submitted.json -# timestamp: 2026-03-16T00:33:16+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_async_response_working.py b/src/adcp/types/generated_poc/media_buy/build_creative_async_response_working.py index 2faaa570..b7c57360 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_async_response_working.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/build_creative_async_response_working.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_request.py b/src/adcp/types/generated_poc/media_buy/build_creative_request.py index 22555f78..9de8e617 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_request.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/build_creative_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_response.py b/src/adcp/types/generated_poc/media_buy/build_creative_response.py index 6c0951ef..5ea7e8a8 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_response.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/build_creative_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py index e8853ad5..262922f1 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/create_media_buy_async_response_input_required.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py index dac799ec..4386bc66 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/create_media_buy_async_response_submitted.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py index 2f8baf08..1a2d57d2 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/create_media_buy_async_response_working.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py index 8fc4293e..3a41ac30 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/create_media_buy_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py index 7ef08fc7..1518219f 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/create_media_buy_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -52,7 +52,7 @@ class CreateMediaBuyResponse3(AdCPBaseModel): Field( description="Task-level status literal. Discriminates this async envelope from the synchronous success shape, whose status field carries a MediaBuyStatus value (pending_creatives, pending_start, active). See task-status.json for the full task-status enum." ), - ] + ] = "submitted" task_id: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py index cc5cf302..3ba00d6a 100644 --- a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py +++ b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_media_buy_delivery_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py index ac1e97ca..f24bd381 100644 --- a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py +++ b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_media_buy_delivery_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/get_media_buys_request.py b/src/adcp/types/generated_poc/media_buy/get_media_buys_request.py index 4174d9eb..d19064f0 100644 --- a/src/adcp/types/generated_poc/media_buy/get_media_buys_request.py +++ b/src/adcp/types/generated_poc/media_buy/get_media_buys_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_media_buys_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/get_media_buys_response.py b/src/adcp/types/generated_poc/media_buy/get_media_buys_response.py index 04e865ac..a1763400 100644 --- a/src/adcp/types/generated_poc/media_buy/get_media_buys_response.py +++ b/src/adcp/types/generated_poc/media_buy/get_media_buys_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_media_buys_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py index 23c63337..10292975 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_async_response_input_required.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py index df425d28..28f9cba2 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_async_response_submitted.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py b/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py index 72ece5a4..8af4b616 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_async_response_working.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/get_products_request.py b/src/adcp/types/generated_poc/media_buy/get_products_request.py index 9b25771f..81295ad9 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_request.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_request.py @@ -1,14 +1,14 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations from enum import Enum -from typing import Annotated, Literal +from typing import Any, Annotated, Literal from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field +from pydantic import ConfigDict, Field, RootModel from ..core import account_ref, brand_ref from ..core import catalog as catalog_1 @@ -25,7 +25,7 @@ class BuyingMode(Enum): refine = "refine" -class Refine(AdCPBaseModel): +class Refine1(AdCPBaseModel): model_config = ConfigDict( extra="forbid", ) @@ -34,7 +34,7 @@ class Refine(AdCPBaseModel): Field( description="Change scoped to the overall request — direction for the selection as a whole." ), - ] + ] = "request" ask: Annotated[ str, Field( @@ -50,20 +50,22 @@ class Action(Enum): more_like_this = "more_like_this" -class Refine1(AdCPBaseModel): +class Refine2(AdCPBaseModel): model_config = ConfigDict( extra="forbid", ) - scope: Annotated[Literal["product"], Field(description="Change scoped to a specific product.")] - id: Annotated[ + scope: Annotated[ + Literal["product"], Field(description="Change scoped to a specific product.") + ] = "product" + product_id: Annotated[ str, Field(description="Product ID from a previous get_products response.", min_length=1) ] action: Annotated[ - Action, + Action | None, Field( - description="'include': return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned)." + description="'include' (default): return this product with updated pricing and data. 'omit': exclude this product from the response. 'more_like_this': find additional products similar to this one (the original is also returned). Optional — when omitted, the seller treats the entry as action: 'include'." ), - ] + ] = Action.include ask: Annotated[ str | None, Field( @@ -79,22 +81,22 @@ class Action3(Enum): finalize = "finalize" -class Refine2(AdCPBaseModel): +class Refine3(AdCPBaseModel): model_config = ConfigDict( extra="forbid", ) scope: Annotated[ Literal["proposal"], Field(description="Change scoped to a specific proposal.") - ] - id: Annotated[ + ] = "proposal" + proposal_id: Annotated[ str, Field(description="Proposal ID from a previous get_products response.", min_length=1) ] action: Annotated[ - Action3, + Action3 | None, Field( - description="'include': return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold — transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests — they represent a commitment to wait for the result." + description="'include' (default): return this proposal with updated allocations and pricing. 'omit': exclude this proposal from the response. 'finalize': request firm pricing and inventory hold — transitions a draft proposal to committed with an expires_at hold window. May trigger seller-side approval (HITL). The buyer should not set a time_budget for finalize requests — they represent a commitment to wait for the result. Optional — when omitted, the seller treats the entry as action: 'include'." ), - ] + ] = Action3.include ask: Annotated[ str | None, Field( @@ -104,6 +106,16 @@ class Refine2(AdCPBaseModel): ] = None +class Refine(RootModel[Refine1 | Refine2 | Refine3]): + root: Annotated[Refine1 | Refine2 | Refine3, Field(discriminator="scope")] + + def __getattr__(self, name: str) -> Any: + """Proxy attribute access to the wrapped type.""" + if name.startswith("_"): + raise AttributeError(name) + return getattr(self.root, name) + + class Field1(Enum): product_id = "product_id" name = "name" @@ -162,7 +174,7 @@ class GetProductsRequest(AdCPBaseModel): ), ] = None refine: Annotated[ - list[Refine | Refine1 | Refine2] | None, + list[Refine] | None, Field( description="Array of change requests for iterating on products and proposals from a previous get_products response. Each entry declares a scope (request, product, or proposal) and what the buyer is asking for. Only valid when buying_mode is 'refine'. The seller responds to each entry via refinement_applied in the response, matched by position.", min_length=1, diff --git a/src/adcp/types/generated_poc/media_buy/get_products_response.py b/src/adcp/types/generated_poc/media_buy/get_products_response.py index 0decaf3f..c762bcf4 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_response.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_response.py @@ -1,27 +1,19 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations from enum import Enum -from typing import Annotated +from typing import Any, Annotated, Literal from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field +from pydantic import ConfigDict, Field, RootModel from ..core import context as context_1 from ..core import duration, error from ..core import ext as ext_1 -from ..core import pagination_response -from ..core import product as product_1 -from ..core import proposal as proposal_1 - - -class Scope(Enum): - request = "request" - product = "product" - proposal = "proposal" +from ..core import pagination_response, product, proposal class Status(Enum): @@ -30,22 +22,64 @@ class Status(Enum): unable = "unable" -class RefinementAppliedItem(AdCPBaseModel): +class RefinementApplied1(AdCPBaseModel): model_config = ConfigDict( extra="forbid", ) scope: Annotated[ - Scope | None, + Literal["request"], + Field(description="Echoes scope 'request' from the corresponding refine entry."), + ] = "request" + status: Annotated[ + Status, + Field( + description="'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled — see notes for details. 'unable': the seller could not fulfill the ask — see notes for why." + ), + ] + notes: Annotated[ + str | None, Field( - description="Echoes the scope from the corresponding refine entry. Allows orchestrators to cross-validate alignment." + description="Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." ), ] = None - id: Annotated[ + + +class RefinementApplied2(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + scope: Annotated[ + Literal["product"], + Field(description="Echoes scope 'product' from the corresponding refine entry."), + ] = "product" + product_id: Annotated[ + str, Field(description="Echoes product_id from the corresponding refine entry.") + ] + status: Annotated[ + Status, + Field( + description="'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled — see notes for details. 'unable': the seller could not fulfill the ask — see notes for why." + ), + ] + notes: Annotated[ str | None, Field( - description="Echoes the id from the corresponding refine entry (for product and proposal scopes)." + description="Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'." ), ] = None + + +class RefinementApplied3(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + scope: Annotated[ + Literal["proposal"], + Field(description="Echoes scope 'proposal' from the corresponding refine entry."), + ] = "proposal" + proposal_id: Annotated[ + str, Field(description="Echoes proposal_id from the corresponding refine entry.") + ] status: Annotated[ Status, Field( @@ -60,7 +94,19 @@ class RefinementAppliedItem(AdCPBaseModel): ] = None -class Scope3(Enum): +class RefinementApplied(RootModel[RefinementApplied1 | RefinementApplied2 | RefinementApplied3]): + root: Annotated[ + RefinementApplied1 | RefinementApplied2 | RefinementApplied3, Field(discriminator="scope") + ] + + def __getattr__(self, name: str) -> Any: + """Proxy attribute access to the wrapped type.""" + if name.startswith("_"): + raise AttributeError(name) + return getattr(self.root, name) + + +class Scope(Enum): products = "products" pricing = "pricing" forecast = "forecast" @@ -72,7 +118,7 @@ class IncompleteItem(AdCPBaseModel): extra="forbid", ) scope: Annotated[ - Scope3, + Scope, Field( description="'products': not all inventory sources were searched. 'pricing': products returned but pricing is absent or unconfirmed. 'forecast': products returned but forecast data is absent. 'proposals': proposals were not generated or are incomplete." ), @@ -92,9 +138,9 @@ class GetProductsResponse(AdCPBaseModel): model_config = ConfigDict( extra="allow", ) - products: Annotated[list[product_1.Product], Field(description="Array of matching products")] + products: Annotated[list[product.Product], Field(description="Array of matching products")] proposals: Annotated[ - list[proposal_1.Proposal] | None, + list[proposal.Proposal] | None, Field( description="Optional array of proposed media plans with budget allocations across products. Publishers include proposals when they can provide strategic guidance based on the brief. Proposals are actionable - buyers can refine them via follow-up get_products calls within the same session, or execute them directly via create_media_buy." ), @@ -116,9 +162,9 @@ class GetProductsResponse(AdCPBaseModel): ), ] = None refinement_applied: Annotated[ - list[RefinementAppliedItem] | None, + list[RefinementApplied] | None, Field( - description="Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'." + description="Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'. Each entry MUST echo the request entry's scope and — for product and proposal scopes — the matching id field (product_id or proposal_id), so orchestrators can cross-validate alignment." ), ] = None incomplete: Annotated[ diff --git a/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py b/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py index 0d42d27c..6b48d60c 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py +++ b/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/list_creative_formats_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py b/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py index 6ffbf490..7fb03fc6 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py +++ b/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/list_creative_formats_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/log_event_request.py b/src/adcp/types/generated_poc/media_buy/log_event_request.py index f694c37d..f9901f07 100644 --- a/src/adcp/types/generated_poc/media_buy/log_event_request.py +++ b/src/adcp/types/generated_poc/media_buy/log_event_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/log_event_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/log_event_response.py b/src/adcp/types/generated_poc/media_buy/log_event_response.py index bb118ce7..bf5d84f7 100644 --- a/src/adcp/types/generated_poc/media_buy/log_event_response.py +++ b/src/adcp/types/generated_poc/media_buy/log_event_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/log_event_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/package_request.py b/src/adcp/types/generated_poc/media_buy/package_request.py index 2fc42d9b..d033ba70 100644 --- a/src/adcp/types/generated_poc/media_buy/package_request.py +++ b/src/adcp/types/generated_poc/media_buy/package_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/package_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/package_update.py b/src/adcp/types/generated_poc/media_buy/package_update.py index c4242384..6e8d9d4f 100644 --- a/src/adcp/types/generated_poc/media_buy/package_update.py +++ b/src/adcp/types/generated_poc/media_buy/package_update.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/package_update.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py index 633252dd..71dd0d03 100644 --- a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py +++ b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/provide_performance_feedback_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py index f956a9f0..692dc604 100644 --- a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py +++ b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/provide_performance_feedback_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_audiences_request.py b/src/adcp/types/generated_poc/media_buy/sync_audiences_request.py index 268297dc..87f1b52c 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_audiences_request.py +++ b/src/adcp/types/generated_poc/media_buy/sync_audiences_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_audiences_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_audiences_response.py b/src/adcp/types/generated_poc/media_buy/sync_audiences_response.py index ab58e9ef..463da976 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_audiences_response.py +++ b/src/adcp/types/generated_poc/media_buy/sync_audiences_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_audiences_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_input_required.py index 5c261f61..89d1d756 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_input_required.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_catalogs_async_response_input_required.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_submitted.py index d6c7c3ad..55c46d8d 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_submitted.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_catalogs_async_response_submitted.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_working.py b/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_working.py index 3e1e0d4e..3cf4a62e 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/sync_catalogs_async_response_working.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_catalogs_async_response_working.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_catalogs_request.py b/src/adcp/types/generated_poc/media_buy/sync_catalogs_request.py index a397df55..665c4c41 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_catalogs_request.py +++ b/src/adcp/types/generated_poc/media_buy/sync_catalogs_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_catalogs_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_catalogs_response.py b/src/adcp/types/generated_poc/media_buy/sync_catalogs_response.py index bae0de3a..664183c4 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_catalogs_response.py +++ b/src/adcp/types/generated_poc/media_buy/sync_catalogs_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_catalogs_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_event_sources_request.py b/src/adcp/types/generated_poc/media_buy/sync_event_sources_request.py index a5db2149..5366da7e 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_event_sources_request.py +++ b/src/adcp/types/generated_poc/media_buy/sync_event_sources_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_event_sources_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/sync_event_sources_response.py b/src/adcp/types/generated_poc/media_buy/sync_event_sources_response.py index 5b44a771..ba202d34 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_event_sources_response.py +++ b/src/adcp/types/generated_poc/media_buy/sync_event_sources_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/sync_event_sources_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py index 3177ef44..6b60ba97 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/update_media_buy_async_response_input_required.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py index 20c9592d..5aaee3cc 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/update_media_buy_async_response_submitted.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py index adfd2a01..cb3089ae 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/update_media_buy_async_response_working.json -# timestamp: 2026-04-16T02:55:59+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py index 16b9584b..f1b86a82 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/update_media_buy_request.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py index fd14338f..58fdd5dc 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/update_media_buy_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/pricing_options/cpa_option.py b/src/adcp/types/generated_poc/pricing_options/cpa_option.py index 971b2d62..c13831a1 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpa_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpa_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/cpa_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -23,7 +23,7 @@ class CpaPricingOption(AdCPBaseModel): ] pricing_model: Annotated[ Literal["cpa"], Field(description="Cost per acquisition (conversion event)") - ] + ] = "cpa" event_type: Annotated[ event_type_1.EventType, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/cpc_option.py b/src/adcp/types/generated_poc/pricing_options/cpc_option.py index 815f8623..a653f916 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpc_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpc_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/cpc_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -21,7 +21,7 @@ class CpcPricingOption(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpc"], Field(description="Cost per click")] + pricing_model: Annotated[Literal["cpc"], Field(description="Cost per click")] = "cpc" currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/cpcv_option.py b/src/adcp/types/generated_poc/pricing_options/cpcv_option.py index b589843a..1293feba 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpcv_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpcv_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/cpcv_option.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -23,7 +23,7 @@ class CpcvPricingOption(AdCPBaseModel): ] pricing_model: Annotated[ Literal["cpcv"], Field(description="Cost per completed view (100% completion)") - ] + ] = "cpcv" currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/cpm_option.py b/src/adcp/types/generated_poc/pricing_options/cpm_option.py index d7285c8c..d8eb3560 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpm_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpm_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/cpm_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -21,7 +21,9 @@ class CpmPricingOption(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpm"], Field(description="Cost per 1,000 impressions")] + pricing_model: Annotated[Literal["cpm"], Field(description="Cost per 1,000 impressions")] = ( + "cpm" + ) currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/cpp_option.py b/src/adcp/types/generated_poc/pricing_options/cpp_option.py index 8b6bbc4e..ed72f5df 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpp_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpp_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/cpp_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -43,7 +43,9 @@ class CppPricingOption(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpp"], Field(description="Cost per Gross Rating Point")] + pricing_model: Annotated[Literal["cpp"], Field(description="Cost per Gross Rating Point")] = ( + "cpp" + ) currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/cpv_option.py b/src/adcp/types/generated_poc/pricing_options/cpv_option.py index d909c7cf..0e377302 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpv_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpv_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/cpv_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -46,7 +46,9 @@ class CpvPricingOption(AdCPBaseModel): pricing_option_id: Annotated[ str, Field(description="Unique identifier for this pricing option within the product") ] - pricing_model: Annotated[Literal["cpv"], Field(description="Cost per view at threshold")] + pricing_model: Annotated[Literal["cpv"], Field(description="Cost per view at threshold")] = ( + "cpv" + ) currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py b/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py index f532ead3..21ced4a1 100644 --- a/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py +++ b/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/flat_rate_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -20,7 +20,7 @@ class Parameters(AdCPBaseModel): ) type: Annotated[ Literal["dooh"], Field(description="Discriminator identifying this as DOOH parameters") - ] + ] = "dooh" sov_percentage: Annotated[ float | None, Field(description="Guaranteed share of voice as a percentage (0-100)", ge=0.0, le=100.0), @@ -63,7 +63,7 @@ class FlatRatePricingOption(AdCPBaseModel): ] pricing_model: Annotated[ Literal["flat_rate"], Field(description="Fixed cost regardless of delivery volume") - ] + ] = "flat_rate" currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/price_breakdown.py b/src/adcp/types/generated_poc/pricing_options/price_breakdown.py index bba71333..8b5d9a1e 100644 --- a/src/adcp/types/generated_poc/pricing_options/price_breakdown.py +++ b/src/adcp/types/generated_poc/pricing_options/price_breakdown.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/price_breakdown.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/pricing_options/price_guidance.py b/src/adcp/types/generated_poc/pricing_options/price_guidance.py index 160f0c0d..bd1a8bf8 100644 --- a/src/adcp/types/generated_poc/pricing_options/price_guidance.py +++ b/src/adcp/types/generated_poc/pricing_options/price_guidance.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/price_guidance.json -# timestamp: 2026-02-23T01:56:40+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/pricing_options/time_option.py b/src/adcp/types/generated_poc/pricing_options/time_option.py index 9fb3f296..af3d972b 100644 --- a/src/adcp/types/generated_poc/pricing_options/time_option.py +++ b/src/adcp/types/generated_poc/pricing_options/time_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/time_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -54,7 +54,7 @@ class TimeBasedPricingOption(AdCPBaseModel): pricing_model: Annotated[ Literal["time"], Field(description="Cost per time unit - rate scales with campaign duration"), - ] + ] = "time" currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/vcpm_option.py b/src/adcp/types/generated_poc/pricing_options/vcpm_option.py index 956c6564..ce8f5554 100644 --- a/src/adcp/types/generated_poc/pricing_options/vcpm_option.py +++ b/src/adcp/types/generated_poc/pricing_options/vcpm_option.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: pricing_options/vcpm_option.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -23,7 +23,7 @@ class VcpmPricingOption(AdCPBaseModel): ] pricing_model: Annotated[ Literal["vcpm"], Field(description="Cost per 1,000 viewable impressions (MRC standard)") - ] + ] = "vcpm" currency: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/property/authorization_result.py b/src/adcp/types/generated_poc/property/authorization_result.py index 4ef1e826..228bd8ac 100644 --- a/src/adcp/types/generated_poc/property/authorization_result.py +++ b/src/adcp/types/generated_poc/property/authorization_result.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/authorization_result.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/base_property_source.py b/src/adcp/types/generated_poc/property/base_property_source.py index b10a845e..6230378c 100644 --- a/src/adcp/types/generated_poc/property/base_property_source.py +++ b/src/adcp/types/generated_poc/property/base_property_source.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/base_property_source.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -19,7 +19,7 @@ class BasePropertySource1(AdCPBaseModel): selection_type: Annotated[ Literal["publisher_tags"], Field(description="Discriminator indicating selection by property tags within a publisher"), - ] + ] = "publisher_tags" publisher_domain: Annotated[ str, Field( @@ -45,7 +45,7 @@ class BasePropertySource2(AdCPBaseModel): Field( description="Discriminator indicating selection by specific property IDs within a publisher" ), - ] + ] = "publisher_ids" publisher_domain: Annotated[ str, Field( @@ -66,7 +66,7 @@ class BasePropertySource3(AdCPBaseModel): selection_type: Annotated[ Literal["identifiers"], Field(description="Discriminator indicating selection by direct identifiers"), - ] + ] = "identifiers" identifiers: Annotated[ list[identifier.Identifier], Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), diff --git a/src/adcp/types/generated_poc/property/create_property_list_request.py b/src/adcp/types/generated_poc/property/create_property_list_request.py index 82b499ec..99fede54 100644 --- a/src/adcp/types/generated_poc/property/create_property_list_request.py +++ b/src/adcp/types/generated_poc/property/create_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/create_property_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/create_property_list_response.py b/src/adcp/types/generated_poc/property/create_property_list_response.py index f5b50eb4..2098aeb4 100644 --- a/src/adcp/types/generated_poc/property/create_property_list_response.py +++ b/src/adcp/types/generated_poc/property/create_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/create_property_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/delete_property_list_request.py b/src/adcp/types/generated_poc/property/delete_property_list_request.py index 92e7626a..5a16575c 100644 --- a/src/adcp/types/generated_poc/property/delete_property_list_request.py +++ b/src/adcp/types/generated_poc/property/delete_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/delete_property_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/delete_property_list_response.py b/src/adcp/types/generated_poc/property/delete_property_list_response.py index a36e8b74..8f569f58 100644 --- a/src/adcp/types/generated_poc/property/delete_property_list_response.py +++ b/src/adcp/types/generated_poc/property/delete_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/delete_property_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/delivery_record.py b/src/adcp/types/generated_poc/property/delivery_record.py index 85d1f9c7..cd9b11b4 100644 --- a/src/adcp/types/generated_poc/property/delivery_record.py +++ b/src/adcp/types/generated_poc/property/delivery_record.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/delivery_record.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/get_property_list_request.py b/src/adcp/types/generated_poc/property/get_property_list_request.py index 936d6db8..4dee7459 100644 --- a/src/adcp/types/generated_poc/property/get_property_list_request.py +++ b/src/adcp/types/generated_poc/property/get_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/get_property_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/get_property_list_response.py b/src/adcp/types/generated_poc/property/get_property_list_response.py index 5fd6c92f..cf25ada3 100644 --- a/src/adcp/types/generated_poc/property/get_property_list_response.py +++ b/src/adcp/types/generated_poc/property/get_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/get_property_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -14,6 +14,7 @@ from ..core import identifier, pagination_response from . import property_list + _list = list # alias to avoid shadowing by field name diff --git a/src/adcp/types/generated_poc/property/list_property_lists_request.py b/src/adcp/types/generated_poc/property/list_property_lists_request.py index c40d1bd6..830464ad 100644 --- a/src/adcp/types/generated_poc/property/list_property_lists_request.py +++ b/src/adcp/types/generated_poc/property/list_property_lists_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/list_property_lists_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/list_property_lists_response.py b/src/adcp/types/generated_poc/property/list_property_lists_response.py index 33b5e61c..13b252d5 100644 --- a/src/adcp/types/generated_poc/property/list_property_lists_response.py +++ b/src/adcp/types/generated_poc/property/list_property_lists_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/list_property_lists_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/property_error.py b/src/adcp/types/generated_poc/property/property_error.py index 00f92856..11330bfc 100644 --- a/src/adcp/types/generated_poc/property/property_error.py +++ b/src/adcp/types/generated_poc/property/property_error.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_error.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/property_feature.py b/src/adcp/types/generated_poc/property/property_feature.py index 9f76d1f1..66ebf465 100644 --- a/src/adcp/types/generated_poc/property/property_feature.py +++ b/src/adcp/types/generated_poc/property/property_feature.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_feature.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/property_feature_definition.py b/src/adcp/types/generated_poc/property/property_feature_definition.py index 208e3eb3..3b13267b 100644 --- a/src/adcp/types/generated_poc/property/property_feature_definition.py +++ b/src/adcp/types/generated_poc/property/property_feature_definition.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_feature_definition.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/property_feature_result.py b/src/adcp/types/generated_poc/property/property_feature_result.py index fdcaa753..6eef56a9 100644 --- a/src/adcp/types/generated_poc/property/property_feature_result.py +++ b/src/adcp/types/generated_poc/property/property_feature_result.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_feature_result.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/property_feature_value.py b/src/adcp/types/generated_poc/property/property_feature_value.py index 748848e2..228d83ac 100644 --- a/src/adcp/types/generated_poc/property/property_feature_value.py +++ b/src/adcp/types/generated_poc/property/property_feature_value.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_feature_value.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/property_list.py b/src/adcp/types/generated_poc/property/property_list.py index 56789720..554e37c2 100644 --- a/src/adcp/types/generated_poc/property/property_list.py +++ b/src/adcp/types/generated_poc/property/property_list.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_list.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/property_list_changed_webhook.py b/src/adcp/types/generated_poc/property/property_list_changed_webhook.py index ceb893de..6edc59b0 100644 --- a/src/adcp/types/generated_poc/property/property_list_changed_webhook.py +++ b/src/adcp/types/generated_poc/property/property_list_changed_webhook.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_list_changed_webhook.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -40,7 +40,9 @@ class PropertyListChangedWebhook(AdCPBaseModel): pattern="^[A-Za-z0-9_.:-]{16,255}$", ), ] - event: Annotated[Literal["property_list_changed"], Field(description="The event type")] + event: Annotated[Literal["property_list_changed"], Field(description="The event type")] = ( + "property_list_changed" + ) list_id: Annotated[str, Field(description="ID of the property list that changed")] list_name: Annotated[str | None, Field(description="Name of the property list")] = None change_summary: Annotated[ diff --git a/src/adcp/types/generated_poc/property/property_list_filters.py b/src/adcp/types/generated_poc/property/property_list_filters.py index 25df439d..9499ba08 100644 --- a/src/adcp/types/generated_poc/property/property_list_filters.py +++ b/src/adcp/types/generated_poc/property/property_list_filters.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_list_filters.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/update_property_list_request.py b/src/adcp/types/generated_poc/property/update_property_list_request.py index 873b948c..6cac4216 100644 --- a/src/adcp/types/generated_poc/property/update_property_list_request.py +++ b/src/adcp/types/generated_poc/property/update_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/update_property_list_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/update_property_list_response.py b/src/adcp/types/generated_poc/property/update_property_list_response.py index 22a65aae..294350cc 100644 --- a/src/adcp/types/generated_poc/property/update_property_list_response.py +++ b/src/adcp/types/generated_poc/property/update_property_list_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/update_property_list_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/validate_property_delivery_request.py b/src/adcp/types/generated_poc/property/validate_property_delivery_request.py index 10783a1f..8d0489dd 100644 --- a/src/adcp/types/generated_poc/property/validate_property_delivery_request.py +++ b/src/adcp/types/generated_poc/property/validate_property_delivery_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/validate_property_delivery_request.json -# timestamp: 2026-04-19T02:40:53+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/validate_property_delivery_response.py b/src/adcp/types/generated_poc/property/validate_property_delivery_response.py index d754ae44..7a53b19f 100644 --- a/src/adcp/types/generated_poc/property/validate_property_delivery_response.py +++ b/src/adcp/types/generated_poc/property/validate_property_delivery_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/validate_property_delivery_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/property/validation_result.py b/src/adcp/types/generated_poc/property/validation_result.py index 62def43e..07779ee0 100644 --- a/src/adcp/types/generated_poc/property/validation_result.py +++ b/src/adcp/types/generated_poc/property/validation_result.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/validation_result.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -22,7 +22,7 @@ class Status(Enum): unidentified = "unidentified" -class Status52(Enum): +class Status56(Enum): passed = "passed" failed = "failed" warning = "warning" @@ -50,7 +50,7 @@ class Feature(AdCPBaseModel): description="Which feature was evaluated. Data features come from the governance agent's feature catalog (e.g., 'mfa_score', 'carbon_score'). Record-level structural checks use reserved namespaces: 'record:list_membership', 'record:excluded', 'delivery:seller_authorization', 'delivery:click_url_presence'. Reserved prefixes: 'record:', 'delivery:'." ), ] - status: Status52 + status: Status56 policy_id: Annotated[ str | None, Field( diff --git a/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_request.py b/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_request.py index 615d91ae..d7327c4d 100644 --- a/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_request.py +++ b/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: protocol/get_adcp_capabilities_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py b/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py index 5b2451b5..32da54c4 100644 --- a/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py +++ b/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: protocol/get_adcp_capabilities_response.json -# timestamp: 2026-04-21T22:41:55+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/signals/activate_signal_request.py b/src/adcp/types/generated_poc/signals/activate_signal_request.py index d74f4693..0d67e4b4 100644 --- a/src/adcp/types/generated_poc/signals/activate_signal_request.py +++ b/src/adcp/types/generated_poc/signals/activate_signal_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: signals/activate_signal_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/signals/activate_signal_response.py b/src/adcp/types/generated_poc/signals/activate_signal_response.py index 703dff3b..54b6c8b6 100644 --- a/src/adcp/types/generated_poc/signals/activate_signal_response.py +++ b/src/adcp/types/generated_poc/signals/activate_signal_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: signals/activate_signal_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/signals/get_signals_request.py b/src/adcp/types/generated_poc/signals/get_signals_request.py index ac55e915..06082f03 100644 --- a/src/adcp/types/generated_poc/signals/get_signals_request.py +++ b/src/adcp/types/generated_poc/signals/get_signals_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: signals/get_signals_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/signals/get_signals_response.py b/src/adcp/types/generated_poc/signals/get_signals_response.py index 29a3beda..1cd33ab8 100644 --- a/src/adcp/types/generated_poc/signals/get_signals_response.py +++ b/src/adcp/types/generated_poc/signals/get_signals_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: signals/get_signals_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_capabilities.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_capabilities.py index 85072cb1..288a2a07 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_capabilities.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_capabilities.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_capabilities.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_request.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_request.py index 30fa9f81..9e6dcc5c 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_request.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_get_offering_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -9,6 +9,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field +from ..core import context as context_1 from ..core import ext as ext_1 @@ -27,12 +28,13 @@ class SiGetOfferingRequest(AdCPBaseModel): offering_id: Annotated[ str, Field(description="Offering identifier from the catalog to get details for") ] - context: Annotated[ + intent: Annotated[ str | None, Field( - description="Optional natural language context about user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." + description="Optional natural language description of user intent for personalized results (e.g., 'mens size 14 near Cincinnati'). Must be anonymous - no PII." ), ] = None + context: context_1.ContextObject | None = None include_products: Annotated[ bool | None, Field(description="Whether to include matching products in the response") ] = False diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_response.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_response.py index 1a3ff85c..eced0212 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_response.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_get_offering_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_get_offering_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_identity.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_identity.py index 2a6e08d6..5fdf30cb 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_identity.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_identity.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_identity.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_request.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_request.py index 90f89b78..9e12ae96 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_request.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_initiate_session_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -9,6 +9,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field +from ..core import context as context_1 from ..core import ext as ext_1 from . import si_capabilities, si_identity @@ -25,9 +26,13 @@ class SiInitiateSessionRequest(AdCPBaseModel): le=99, ), ] = None - context: Annotated[ - str, Field(description="Conversation handoff from the host describing what the user needs") + intent: Annotated[ + str, + Field( + description="Natural language description of user intent — the conversation handoff from the host describing what the user needs from the brand agent" + ), ] + context: context_1.ContextObject | None = None identity: si_identity.SiIdentity media_buy_id: Annotated[ str | None, Field(description="AdCP media buy ID if session was triggered by advertising") diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_response.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_response.py index 816a3781..deb1393a 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_response.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_initiate_session_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_request.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_request.py index 3d86dee5..29ec21bc 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_request.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_send_message_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_response.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_response.py index 7971da9b..15f5a878 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_response.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_send_message_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_send_message_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_request.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_request.py index 445c750e..b5156cf0 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_request.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_terminate_session_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_response.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_response.py index 3126badb..be77b3c4 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_response.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_terminate_session_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/sponsored_intelligence/si_ui_element.py b/src/adcp/types/generated_poc/sponsored_intelligence/si_ui_element.py index 9bcfb69d..06dba7fd 100644 --- a/src/adcp/types/generated_poc/sponsored_intelligence/si_ui_element.py +++ b/src/adcp/types/generated_poc/sponsored_intelligence/si_ui_element.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: sponsored_intelligence/si_ui_element.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/tmp/available_package.py b/src/adcp/types/generated_poc/tmp/available_package.py index 7929bd59..6f2c5fe4 100644 --- a/src/adcp/types/generated_poc/tmp/available_package.py +++ b/src/adcp/types/generated_poc/tmp/available_package.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/available_package.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/tmp/context_match_request.py b/src/adcp/types/generated_poc/tmp/context_match_request.py index 6c77b372..dd2ea526 100644 --- a/src/adcp/types/generated_poc/tmp/context_match_request.py +++ b/src/adcp/types/generated_poc/tmp/context_match_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/context_match_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -191,7 +191,7 @@ class ContextMatchRequest(AdCPBaseModel): type: Annotated[ Literal["context_match_request"], Field(description="Message type discriminator for deserialization."), - ] + ] = "context_match_request" protocol_version: Annotated[ str | None, Field( diff --git a/src/adcp/types/generated_poc/tmp/context_match_response.py b/src/adcp/types/generated_poc/tmp/context_match_response.py index 40bae7cd..2255b6f0 100644 --- a/src/adcp/types/generated_poc/tmp/context_match_response.py +++ b/src/adcp/types/generated_poc/tmp/context_match_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/context_match_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -39,7 +39,7 @@ class ContextMatchResponse(AdCPBaseModel): type: Annotated[ Literal["context_match_response"], Field(description="Message type discriminator for deserialization."), - ] + ] = "context_match_response" request_id: Annotated[ str, Field(description="Echoed request identifier from the context match request") ] diff --git a/src/adcp/types/generated_poc/tmp/error.py b/src/adcp/types/generated_poc/tmp/error.py index cbc46c8a..be2c4c1f 100644 --- a/src/adcp/types/generated_poc/tmp/error.py +++ b/src/adcp/types/generated_poc/tmp/error.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/error.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -26,7 +26,7 @@ class TmpError(AdCPBaseModel): ) type: Annotated[ Literal["error"], Field(description="Message type discriminator for deserialization.") - ] + ] = "error" request_id: Annotated[ str, Field(description="Echoed request identifier from the original request") ] diff --git a/src/adcp/types/generated_poc/tmp/identity_match_request.py b/src/adcp/types/generated_poc/tmp/identity_match_request.py index 0006f731..ac2cb404 100644 --- a/src/adcp/types/generated_poc/tmp/identity_match_request.py +++ b/src/adcp/types/generated_poc/tmp/identity_match_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/identity_match_request.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -68,7 +68,7 @@ class IdentityMatchRequest(AdCPBaseModel): type: Annotated[ Literal["identity_match_request"], Field(description="Message type discriminator for deserialization."), - ] + ] = "identity_match_request" protocol_version: Annotated[ str | None, Field( diff --git a/src/adcp/types/generated_poc/tmp/identity_match_response.py b/src/adcp/types/generated_poc/tmp/identity_match_response.py index ac140cf9..2d622b36 100644 --- a/src/adcp/types/generated_poc/tmp/identity_match_response.py +++ b/src/adcp/types/generated_poc/tmp/identity_match_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/identity_match_response.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations @@ -17,7 +17,7 @@ class IdentityMatchResponse(AdCPBaseModel): type: Annotated[ Literal["identity_match_response"], Field(description="Message type discriminator for deserialization."), - ] + ] = "identity_match_response" request_id: Annotated[ str, Field(description="Echoed request identifier from the identity match request") ] diff --git a/src/adcp/types/generated_poc/tmp/offer.py b/src/adcp/types/generated_poc/tmp/offer.py index d9454aad..1b983213 100644 --- a/src/adcp/types/generated_poc/tmp/offer.py +++ b/src/adcp/types/generated_poc/tmp/offer.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/offer.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/tmp/offer_price.py b/src/adcp/types/generated_poc/tmp/offer_price.py index 018d9b16..4bbf7600 100644 --- a/src/adcp/types/generated_poc/tmp/offer_price.py +++ b/src/adcp/types/generated_poc/tmp/offer_price.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/offer_price.json -# timestamp: 2026-04-02T22:34:46+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/tmp/provider_registration.py b/src/adcp/types/generated_poc/tmp/provider_registration.py index e9e5a259..765c87c2 100644 --- a/src/adcp/types/generated_poc/tmp/provider_registration.py +++ b/src/adcp/types/generated_poc/tmp/provider_registration.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: tmp/provider_registration.json -# timestamp: 2026-04-18T19:31:26+00:00 +# timestamp: 2026-04-22T04:27:52+00:00 from __future__ import annotations diff --git a/tests/test_literal_discriminator_defaults.py b/tests/test_literal_discriminator_defaults.py new file mode 100644 index 00000000..4232acaa --- /dev/null +++ b/tests/test_literal_discriminator_defaults.py @@ -0,0 +1,171 @@ +"""Tests for the post-generation ``Literal[]`` defaults +injection in ``scripts/post_generate_fixes.py``. + +The injection turns spec-required discriminator fields (whose type is +``Literal['x']`` with a single value) into defaulted fields. Wire +consumers are unaffected — the Literal type still enforces the tag. +In-process construction becomes ergonomic — ``TextContent(content='x')`` +works without having to repeat ``asset_type='text'``. + +These tests pin the behavior across a sampling of Asset, Pricing, and +Response types so a future regen that breaks the injection fails loudly +at the right layer. +""" + +from __future__ import annotations + +import pytest + + +class TestAssetContentDefaults: + """Asset-content types all default their ``asset_type`` + discriminator to the correct tag.""" + + def test_text_content_defaults_asset_type(self) -> None: + from adcp.types import TextContent + + t = TextContent(content="hello") + assert t.asset_type == "text" + assert t.content == "hello" + + def test_html_content_defaults_asset_type(self) -> None: + from adcp.types import HtmlContent + + h = HtmlContent(content="

x

") + assert h.asset_type == "html" + + def test_css_content_defaults_asset_type(self) -> None: + from adcp.types import CssContent + + c = CssContent(content="body{}") + assert c.asset_type == "css" + + def test_javascript_content_defaults_asset_type(self) -> None: + from adcp.types import JavascriptContent + + j = JavascriptContent(content="alert(1)") + assert j.asset_type == "javascript" + + def test_url_content_defaults_asset_type(self) -> None: + from adcp.types import UrlContent + + u = UrlContent(url="https://example.com/asset.jpg") + assert u.asset_type == "url" + + +class TestVastDaastDiscriminators: + """VAST/DAAST have two discriminators: ``asset_type`` (vast/daast) + AND ``delivery_type`` (url/inline). Both are single-value Literals + per the spec's oneOf-of-oneOfs structure; both get defaults.""" + + def test_url_vast_asset_defaults_both_discriminators(self) -> None: + from adcp.types.aliases import UrlVastAsset + + a = UrlVastAsset(url="https://vast.example.com/ad.xml") + assert a.asset_type == "vast" + assert a.delivery_type == "url" + + def test_inline_vast_asset_defaults_both_discriminators(self) -> None: + from adcp.types.aliases import InlineVastAsset + + a = InlineVastAsset(content="...") + assert a.asset_type == "vast" + assert a.delivery_type == "inline" + + def test_url_daast_asset_defaults_both_discriminators(self) -> None: + from adcp.types.aliases import UrlDaastAsset + + a = UrlDaastAsset(url="https://daast.example.com/ad.xml") + assert a.asset_type == "daast" + assert a.delivery_type == "url" + + +class TestDefaultsPreserveValidation: + """The injected defaults are a construction convenience. The + ``Literal`` type still rejects any OTHER value passed explicitly — + defaulting doesn't weaken validation.""" + + def test_wrong_explicit_asset_type_rejected(self) -> None: + from pydantic import ValidationError + + from adcp.types import TextContent + + with pytest.raises(ValidationError): + TextContent(asset_type="html", content="x") # type: ignore[arg-type] + + def test_wrong_explicit_delivery_type_rejected(self) -> None: + from pydantic import ValidationError + + from adcp.types.aliases import UrlVastAsset + + with pytest.raises(ValidationError): + UrlVastAsset( + delivery_type="inline", # type: ignore[arg-type] + url="https://vast.example.com/ad.xml", + ) + + +class TestDefaultsHonourWireFormat: + """Validating a dict (wire format) still works — the defaults are + injected via field metadata, not by pre-filling the input.""" + + def test_text_content_from_wire_dict(self) -> None: + from adcp.types import TextContent + + t = TextContent.model_validate({"asset_type": "text", "content": "hi"}) + assert t.asset_type == "text" + assert t.content == "hi" + + def test_text_content_from_wire_dict_without_asset_type_still_works(self) -> None: + """Wire consumers that omit the discriminator also get the + default — useful for minimal client implementations.""" + from adcp.types import TextContent + + t = TextContent.model_validate({"content": "hi"}) + assert t.asset_type == "text" + + +class TestInjectorBehavior: + """Meta-tests pinning the injector's pattern-match semantics. If + these fail, the post-gen script's scope has drifted.""" + + def test_injector_skips_multi_value_literals(self) -> None: + """``Literal['a', 'b']`` fields stay required — there's no + single correct default. The spec is saying "user must pick", + and we must not pretend otherwise.""" + import ast + + from scripts.post_generate_fixes import _extract_single_literal_value + + # Annotated[Literal['a', 'b'], ...] + module = ast.parse("x: Annotated[Literal['a', 'b'], Field()]") + ann = module.body[0].annotation # type: ignore[attr-defined] + assert _extract_single_literal_value(ann) is None + + def test_injector_extracts_single_literal_value(self) -> None: + import ast + + from scripts.post_generate_fixes import _extract_single_literal_value + + module = ast.parse("x: Annotated[Literal['text'], Field()]") + ann = module.body[0].annotation # type: ignore[attr-defined] + assert _extract_single_literal_value(ann) == "text" + + def test_injector_extracts_bare_literal(self) -> None: + """``Literal['x']`` without Annotated wrap also works.""" + import ast + + from scripts.post_generate_fixes import _extract_single_literal_value + + module = ast.parse("x: Literal['text']") + ann = module.body[0].annotation # type: ignore[attr-defined] + assert _extract_single_literal_value(ann) == "text" + + def test_injector_skips_non_literal_annotations(self) -> None: + import ast + + from scripts.post_generate_fixes import _extract_single_literal_value + + module = ast.parse("x: str") + ann = module.body[0].annotation # type: ignore[attr-defined] + assert _extract_single_literal_value(ann) is None