diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc182a087..ccea9484a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,10 +111,13 @@ jobs: run: | VERSION=$(cat src/adcp/ADCP_VERSION) echo "ADCP_VERSION=$VERSION" - # Check if version contains pre-release identifiers (alpha, beta, rc) - if echo "$VERSION" | grep -qE '(alpha|beta|rc)'; then + # Skip regeneration + drift check for pre-release tags (alpha/beta/rc) + # and for `latest`, which is a moving dev snapshot — the committed + # generated types are frozen against the bundle we last synced, and + # CI's fresh sync against today's `latest.tgz` is expected to drift. + if echo "$VERSION" | grep -qE '(alpha|beta|rc)' || [ "$VERSION" = "latest" ]; then echo "is_prerelease=true" >> $GITHUB_OUTPUT - echo "Pre-release version detected - will skip schema sync (may not be publicly accessible)" + echo "Pre-release / latest version detected - will skip schema sync" else echo "is_prerelease=false" >> $GITHUB_OUTPUT echo "Stable version - will sync schemas from upstream" diff --git a/pyproject.toml b/pyproject.toml index 9ba628fd5..2346660f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "adcp" -version = "3.12.0" +version = "4.0.0b1" description = "Official Python client for the Ad Context Protocol (AdCP)" authors = [ {name = "AdCP Community", email = "maintainers@adcontextprotocol.org"} @@ -14,7 +14,7 @@ requires-python = ">=3.10" license = {text = "Apache-2.0"} keywords = ["adcp", "mcp", "a2a", "protocol", "advertising"] classifiers = [ - "Development Status :: 3 - Alpha", + "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3", @@ -45,7 +45,10 @@ dev = [ "mypy>=1.0.0", "black>=23.0.0", "ruff>=0.1.0", - "datamodel-code-generator[http]>=0.35.0", + # Pin to exact version: codegen's variant numbering (e.g. CreateMediaBuyResponse1 vs + # CreateMediaBuyResponse) shifts between versions, producing diff churn and breaking + # generated-code imports that reference specific suffixes. + "datamodel-code-generator[http]==0.56.1", ] docs = [ "pdoc3>=0.10.0", @@ -150,6 +153,6 @@ skips = ["B101"] # Allow assert in code (we're not using -O optimization) [dependency-groups] dev = [ - "datamodel-code-generator>=0.35.0", + "datamodel-code-generator==0.56.1", "pre-commit>=4.4.0", ] diff --git a/schemas/cache/.hashes.json b/schemas/cache/.hashes.json deleted file mode 100644 index 7985b9c9a..000000000 --- a/schemas/cache/.hashes.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "https://adcontextprotocol.org/schemas/latest/index.json": "2dfc2ef682b77180b0c9edb67f406bede432fd20f1980019af06a97159859ff1" -} \ No newline at end of file diff --git a/schemas/cache/a2ui/bound-value.json b/schemas/cache/a2ui/bound-value.json new file mode 100644 index 000000000..94490eaad --- /dev/null +++ b/schemas/cache/a2ui/bound-value.json @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A2UI Bound Value", + "description": "A value that can be a literal or bound to a path in the data model", + "oneOf": [ + { + "type": "object", + "description": "Literal string value", + "properties": { + "literalString": { + "type": "string", + "description": "Static string value" + } + }, + "required": [ + "literalString" + ], + "additionalProperties": false + }, + { + "type": "object", + "description": "Literal number value", + "properties": { + "literalNumber": { + "type": "number", + "description": "Static number value" + } + }, + "required": [ + "literalNumber" + ], + "additionalProperties": false + }, + { + "type": "object", + "description": "Literal boolean value", + "properties": { + "literalBoolean": { + "type": "boolean", + "description": "Static boolean value" + } + }, + "required": [ + "literalBoolean" + ], + "additionalProperties": false + }, + { + "type": "object", + "description": "Path to data model value", + "properties": { + "path": { + "type": "string", + "description": "JSON pointer path to value in data model (e.g., '/products/0/title')" + } + }, + "required": [ + "path" + ], + "additionalProperties": false + }, + { + "type": "object", + "description": "Literal with path binding (sets default and binds)", + "properties": { + "literalString": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "literalString", + "path" + ], + "additionalProperties": false + } + ] +} \ No newline at end of file diff --git a/schemas/cache/a2ui/si-catalog.json b/schemas/cache/a2ui/si-catalog.json new file mode 100644 index 000000000..9596f806a --- /dev/null +++ b/schemas/cache/a2ui/si-catalog.json @@ -0,0 +1,426 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "SI Component Catalog", + "description": "A2UI component catalog for Sponsored Intelligence", + "definitions": { + "Text": { + "type": "object", + "description": "Text display component", + "properties": { + "text": { + "$ref": "bound-value.json", + "description": "Text content to display" + }, + "variant": { + "type": "string", + "enum": [ + "body", + "heading", + "caption", + "label" + ], + "default": "body" + } + }, + "required": [ + "text" + ] + }, + "Button": { + "type": "object", + "description": "Interactive button component", + "properties": { + "label": { + "$ref": "bound-value.json", + "description": "Button label text" + }, + "action": { + "type": "object", + "description": "Action to trigger on click", + "properties": { + "name": { + "type": "string", + "description": "Action identifier" + }, + "context": { + "type": "object", + "description": "Context data to include with action", + "additionalProperties": { + "$ref": "bound-value.json" + } + } + }, + "required": [ + "name" + ] + }, + "variant": { + "type": "string", + "enum": [ + "primary", + "secondary", + "text" + ], + "default": "primary" + }, + "disabled": { + "$ref": "bound-value.json" + } + }, + "required": [ + "label", + "action" + ] + }, + "Link": { + "type": "object", + "description": "Hyperlink component", + "properties": { + "label": { + "$ref": "bound-value.json", + "description": "Link text" + }, + "url": { + "$ref": "bound-value.json", + "description": "URL to navigate to" + }, + "external": { + "type": "boolean", + "description": "Opens in new tab if true", + "default": true + } + }, + "required": [ + "label", + "url" + ] + }, + "Image": { + "type": "object", + "description": "Image display component", + "properties": { + "src": { + "$ref": "bound-value.json", + "description": "Image source URL" + }, + "alt": { + "$ref": "bound-value.json", + "description": "Alt text for accessibility" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + } + }, + "required": [ + "src", + "alt" + ] + }, + "Card": { + "type": "object", + "description": "Card container for grouped content", + "properties": { + "title": { + "$ref": "bound-value.json", + "description": "Card title" + }, + "subtitle": { + "$ref": "bound-value.json", + "description": "Card subtitle" + }, + "image": { + "$ref": "bound-value.json", + "description": "Card image URL" + }, + "badge": { + "$ref": "bound-value.json", + "description": "Badge text (e.g., 'New', 'Sale')" + }, + "action": { + "type": "object", + "description": "Action to trigger on card click", + "properties": { + "name": { + "type": "string" + }, + "context": { + "type": "object", + "additionalProperties": { + "$ref": "bound-value.json" + } + } + }, + "required": [ + "name" + ] + }, + "children": { + "type": "array", + "description": "Child component IDs", + "items": { + "type": "string" + } + } + }, + "required": [ + "title" + ] + }, + "ProductCard": { + "type": "object", + "description": "Product display card (SI-specific)", + "properties": { + "title": { + "$ref": "bound-value.json", + "description": "Product name" + }, + "price": { + "$ref": "bound-value.json", + "description": "Price display string" + }, + "image": { + "$ref": "bound-value.json", + "description": "Product image URL" + }, + "description": { + "$ref": "bound-value.json", + "description": "Product description" + }, + "badge": { + "$ref": "bound-value.json", + "description": "Badge text (e.g., 'Best Seller')" + }, + "ctaLabel": { + "$ref": "bound-value.json", + "description": "CTA button label" + }, + "action": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "context": { + "type": "object", + "additionalProperties": { + "$ref": "bound-value.json" + } + } + }, + "required": [ + "name" + ] + } + }, + "required": [ + "title", + "price" + ] + }, + "List": { + "type": "object", + "description": "Data-bound list component", + "properties": { + "items": { + "$ref": "bound-value.json", + "description": "Path to array in data model" + }, + "template": { + "type": "object", + "description": "Template for list items", + "properties": { + "componentId": { + "type": "string", + "description": "ID of component to use as template" + } + }, + "required": [ + "componentId" + ] + }, + "emptyMessage": { + "$ref": "bound-value.json", + "description": "Message to show when list is empty" + }, + "layout": { + "type": "string", + "enum": [ + "vertical", + "horizontal", + "grid" + ], + "default": "vertical" + } + }, + "required": [ + "items", + "template" + ] + }, + "Row": { + "type": "object", + "description": "Horizontal layout container", + "properties": { + "children": { + "type": "array", + "description": "Child component IDs", + "items": { + "type": "string" + } + }, + "gap": { + "type": "string", + "description": "Gap between children", + "default": "8px" + }, + "align": { + "type": "string", + "enum": [ + "start", + "center", + "end", + "stretch" + ], + "default": "center" + }, + "justify": { + "type": "string", + "enum": [ + "start", + "center", + "end", + "between", + "around" + ], + "default": "start" + } + }, + "required": [ + "children" + ] + }, + "Column": { + "type": "object", + "description": "Vertical layout container", + "properties": { + "children": { + "type": "array", + "description": "Child component IDs", + "items": { + "type": "string" + } + }, + "gap": { + "type": "string", + "description": "Gap between children", + "default": "8px" + }, + "align": { + "type": "string", + "enum": [ + "start", + "center", + "end", + "stretch" + ], + "default": "stretch" + } + }, + "required": [ + "children" + ] + }, + "IntegrationAction": { + "type": "object", + "description": "MCP/A2A integration action button (SI-specific)", + "properties": { + "type": { + "type": "string", + "enum": [ + "mcp", + "a2a" + ], + "description": "Integration type" + }, + "label": { + "$ref": "bound-value.json", + "description": "Button label" + }, + "url": { + "$ref": "bound-value.json", + "description": "Integration endpoint URL" + }, + "highlighted": { + "type": "boolean", + "description": "Visually emphasize this action", + "default": false + } + }, + "required": [ + "type", + "label" + ] + }, + "AppHandoff": { + "type": "object", + "description": "Platform app handoff (SI-specific)", + "properties": { + "apps": { + "type": "object", + "description": "Platform-specific app configurations", + "additionalProperties": { + "type": "object", + "properties": { + "appId": { + "type": "string" + }, + "deepLink": { + "type": "string" + }, + "url": { + "type": "string", + "format": "uri" + } + } + } + } + }, + "required": [ + "apps" + ] + } + }, + "type": "object", + "properties": { + "catalogId": { + "type": "string", + "const": "si-standard", + "description": "SI standard component catalog" + }, + "components": { + "type": "array", + "description": "Available component types", + "items": { + "type": "string", + "enum": [ + "Text", + "Button", + "Link", + "Image", + "Card", + "ProductCard", + "List", + "Row", + "Column", + "IntegrationAction", + "AppHandoff" + ] + } + } + } +} \ No newline at end of file diff --git a/schemas/cache/a2ui/surface.json b/schemas/cache/a2ui/surface.json index baf1865d4..40aba240d 100644 --- a/schemas/cache/a2ui/surface.json +++ b/schemas/cache/a2ui/surface.json @@ -1,38 +1,38 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "A2UI Surface", "description": "A contiguous UI region containing components", + "type": "object", "properties": { + "surfaceId": { + "type": "string", + "description": "Unique identifier for this surface" + }, "catalogId": { - "default": "standard", + "type": "string", "description": "Component catalog to use for rendering", - "type": "string" + "default": "standard" }, "components": { + "type": "array", "description": "Flat list of components (adjacency list structure)", "items": { "$ref": "component.json" - }, - "type": "array" - }, - "dataModel": { - "additionalProperties": true, - "description": "Application data that components can bind to", - "type": "object" + } }, "rootId": { - "description": "ID of the root component (if not specified, first component is root)", - "type": "string" + "type": "string", + "description": "ID of the root component (if not specified, first component is root)" }, - "surfaceId": { - "description": "Unique identifier for this surface", - "type": "string" + "dataModel": { + "type": "object", + "description": "Application data that components can bind to", + "additionalProperties": true } }, "required": [ "surfaceId", "components" ], - "title": "A2UI Surface", - "type": "object" + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/a2ui/user-action.json b/schemas/cache/a2ui/user-action.json new file mode 100644 index 000000000..9c9a9ccc6 --- /dev/null +++ b/schemas/cache/a2ui/user-action.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A2UI User Action", + "description": "User interaction event sent from client to agent", + "type": "object", + "properties": { + "surfaceId": { + "type": "string", + "description": "ID of the surface where the action occurred" + }, + "componentId": { + "type": "string", + "description": "ID of the component that triggered the action" + }, + "action": { + "type": "object", + "description": "The action that was triggered", + "properties": { + "name": { + "type": "string", + "description": "Action identifier (e.g., 'view_product', 'add_to_cart')" + }, + "context": { + "type": "object", + "description": "Context data resolved from data model bindings", + "additionalProperties": true + } + }, + "required": [ + "name" + ], + "additionalProperties": true + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "When the action occurred" + } + }, + "required": [ + "surfaceId", + "componentId", + "action" + ], + "additionalProperties": true +} \ No newline at end of file diff --git a/schemas/cache/account/get-account-financials-request.json b/schemas/cache/account/get-account-financials-request.json index dc7985b2d..c5d0dd324 100644 --- a/schemas/cache/account/get-account-financials-request.json +++ b/schemas/cache/account/get-account-financials-request.json @@ -1,17 +1,45 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Get Account Financials Request", "description": "Request financial status for an operator-billed account. Returns spend summary, credit/balance status, and invoice history. Only applicable when the seller declares account_financials capability.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "account": { + "$ref": "../core/account-ref.json", + "description": "Account to query financials for. Must be an operator-billed account." + }, + "period": { + "$ref": "../core/date-range.json", + "description": "Date range for the spend summary. Defaults to the current billing cycle if omitted." + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "account" + ], + "additionalProperties": true, "examples": [ { + "description": "Query by account ID for current billing cycle", "data": { "account": { "account_id": "acc_acme_001" } - }, - "description": "Query by account ID for current billing cycle" + } }, { + "description": "Query by natural key for a specific period", "data": { "account": { "brand": { @@ -20,44 +48,22 @@ "operator": "acme-corp.com" }, "period": { - "end": "2026-01-31", - "start": "2026-01-01" + "start": "2026-01-01", + "end": "2026-01-31" } - }, - "description": "Query by natural key for a specific period" + } }, { + "description": "Agency querying financials for a client account", "data": { "account": { "brand": { - "brand_id": "spark", - "domain": "nova-brands.com" + "domain": "nova-brands.com", + "brand_id": "spark" }, "operator": "pinnacle-media.com" } - }, - "description": "Agency querying financials for a client account" - } - ], - "properties": { - "account": { - "$ref": "../core/account-ref.json", - "description": "Account to query financials for. Must be an operator-billed account." - }, - "context": { - "$ref": "../core/context.json" - }, - "ext": { - "$ref": "../core/ext.json" - }, - "period": { - "$ref": "../core/date-range.json", - "description": "Date range for the spend summary. Defaults to the current billing cycle if omitted." + } } - }, - "required": [ - "account" - ], - "title": "Get Account Financials Request", - "type": "object" + ] } \ No newline at end of file diff --git a/schemas/cache/account/get-account-financials-response.json b/schemas/cache/account/get-account-financials-response.json index ecaa75023..8bd243278 100644 --- a/schemas/cache/account/get-account-financials-response.json +++ b/schemas/cache/account/get-account-financials-response.json @@ -1,200 +1,151 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Account Financials Response", "description": "Financial status for an operator-billed account. Returns spend summary, credit/balance status, payment status, and invoice history. The level of detail varies by seller \u2014 only account, currency, and period are guaranteed on success.", - "examples": [ + "type": "object", + "oneOf": [ { - "data": { + "title": "GetAccountFinancialsSuccess", + "description": "Financial data retrieved successfully", + "type": "object", + "properties": { "account": { - "account_id": "acc_acme_001" + "$ref": "../core/account-ref.json", + "description": "Account reference, echoed from the request" }, - "credit": { - "available_credit": 54770.0, - "credit_limit": 100000.0, - "utilization_percent": 45.23 + "currency": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "description": "ISO 4217 currency code for all monetary amounts in this response" }, - "currency": "USD", - "invoices": [ - { - "amount": 38500.0, - "due_date": "2026-02-28", - "invoice_id": "inv_2026_01", - "paid_date": "2026-02-15", - "period": { - "end": "2026-01-31", - "start": "2026-01-01" - }, - "status": "paid" - } - ], - "payment_status": "current", - "payment_terms": "net_30", "period": { - "end": "2026-02-28", - "start": "2026-02-01" - }, - "spend": { - "media_buy_count": 3, - "total_spend": 45230.0 - }, - "timezone": "America/New_York" - }, - "description": "Credit account \u2014 current, with invoice history" - }, - { - "data": { - "account": { - "brand": { - "domain": "acme-corp.com" - }, - "operator": "acme-corp.com" - }, - "balance": { - "available": 1800.0, - "last_top_up": { - "amount": 10000.0, - "date": "2026-02-01" - } + "$ref": "../core/date-range.json", + "description": "The actual period covered by spend data. May differ from the requested period if the seller adjusts to billing cycle boundaries." }, - "currency": "USD", - "payment_status": "current", - "payment_terms": "prepay", - "period": { - "end": "2026-02-28", - "start": "2026-02-01" + "timezone": { + "type": "string", + "description": "IANA timezone of the seller's billing day boundaries (e.g., 'America/New_York'). All dates in this response \u2014 period, invoice periods, due dates \u2014 are calendar dates in this timezone. Buyers in a different timezone should expect spend boundaries to differ from their own calendar day." }, "spend": { - "media_buy_count": 2, - "total_spend": 8200.0 + "type": "object", + "description": "Spend summary for the period", + "properties": { + "total_spend": { + "type": "number", + "minimum": 0, + "description": "Total spend in the period, in currency" + }, + "media_buy_count": { + "type": "integer", + "minimum": 0, + "description": "Number of active media buys in the period" + } + }, + "required": [ + "total_spend" + ] }, - "timezone": "America/Los_Angeles" - }, - "description": "Prepay account with low balance" - }, - { - "data": { - "errors": [ - { - "code": "UNSUPPORTED_FEATURE", - "message": "Financial data is not available for agent-billed accounts. The agent's own billing system is the source of truth." - } - ] - }, - "description": "Agent-billed account \u2014 not supported" - } - ], - "oneOf": [ - { - "additionalProperties": true, - "description": "Financial data retrieved successfully", - "not": { - "required": [ - "errors" - ] - }, - "properties": { - "account": { - "$ref": "../core/account-ref.json", - "description": "Account reference, echoed from the request" + "credit": { + "type": "object", + "description": "Credit status. Present for credit-based accounts (payment_terms like net_30).", + "properties": { + "credit_limit": { + "type": "number", + "minimum": 0, + "description": "Maximum outstanding balance allowed" + }, + "available_credit": { + "type": "number", + "description": "Remaining credit available (credit_limit minus outstanding balance)" + }, + "utilization_percent": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Credit utilization as a percentage (0-100)" + } + }, + "required": [ + "credit_limit", + "available_credit" + ] }, "balance": { + "type": "object", "description": "Prepay balance. Present for prepay accounts.", "properties": { "available": { - "description": "Remaining prepaid balance", + "type": "number", "minimum": 0, - "type": "number" + "description": "Remaining prepaid balance" }, "last_top_up": { + "type": "object", "description": "Most recent balance top-up", "properties": { "amount": { - "description": "Top-up amount", + "type": "number", "minimum": 0, - "type": "number" + "description": "Top-up amount" }, "date": { - "description": "Date of top-up", + "type": "string", "format": "date", - "type": "string" + "description": "Date of top-up" } }, "required": [ "amount", "date" - ], - "type": "object" + ] } }, "required": [ "available" - ], - "type": "object" + ] }, - "context": { - "$ref": "../core/context.json" - }, - "credit": { - "description": "Credit status. Present for credit-based accounts (payment_terms like net_30).", - "properties": { - "available_credit": { - "description": "Remaining credit available (credit_limit minus outstanding balance)", - "type": "number" - }, - "credit_limit": { - "description": "Maximum outstanding balance allowed", - "minimum": 0, - "type": "number" - }, - "utilization_percent": { - "description": "Credit utilization as a percentage (0-100)", - "maximum": 100, - "minimum": 0, - "type": "number" - } - }, - "required": [ - "credit_limit", - "available_credit" + "payment_status": { + "type": "string", + "enum": [ + "current", + "past_due", + "suspended" ], - "type": "object" + "description": "Overall payment status. current: all obligations met. past_due: one or more invoices overdue. suspended: account suspended due to payment issues." }, - "currency": { - "description": "ISO 4217 currency code for all monetary amounts in this response", - "pattern": "^[A-Z]{3}$", - "type": "string" - }, - "ext": { - "$ref": "../core/ext.json" + "payment_terms": { + "type": "string", + "enum": [ + "net_15", + "net_30", + "net_45", + "net_60", + "net_90", + "prepay" + ], + "description": "Payment terms in effect for this account" }, "invoices": { + "type": "array", "description": "Recent invoices. Sellers may limit the number returned.", "items": { + "type": "object", "properties": { - "amount": { - "description": "Invoice total in currency", - "minimum": 0, - "type": "number" - }, - "due_date": { - "description": "Payment due date", - "format": "date", - "type": "string" - }, "invoice_id": { - "description": "Seller-assigned invoice identifier", - "type": "string" - }, - "paid_date": { - "description": "Date payment was received. Present when status is 'paid'.", - "format": "date", - "type": "string" + "type": "string", + "description": "Seller-assigned invoice identifier" }, "period": { "$ref": "../core/date-range.json", "description": "Billing period covered by this invoice" }, + "amount": { + "type": "number", + "minimum": 0, + "description": "Invoice total in currency" + }, "status": { - "description": "Invoice status", + "type": "string", "enum": [ "draft", "issued", @@ -202,65 +153,31 @@ "past_due", "void" ], - "type": "string" + "description": "Invoice status" + }, + "due_date": { + "type": "string", + "format": "date", + "description": "Payment due date" + }, + "paid_date": { + "type": "string", + "format": "date", + "description": "Date payment was received. Present when status is 'paid'." } }, "required": [ "invoice_id", "amount", "status" - ], - "type": "object" - }, - "type": "array" - }, - "payment_status": { - "description": "Overall payment status. current: all obligations met. past_due: one or more invoices overdue. suspended: account suspended due to payment issues.", - "enum": [ - "current", - "past_due", - "suspended" - ], - "type": "string" - }, - "payment_terms": { - "description": "Payment terms in effect for this account", - "enum": [ - "net_15", - "net_30", - "net_45", - "net_60", - "net_90", - "prepay" - ], - "type": "string" - }, - "period": { - "$ref": "../core/date-range.json", - "description": "The actual period covered by spend data. May differ from the requested period if the seller adjusts to billing cycle boundaries." + ] + } }, - "spend": { - "description": "Spend summary for the period", - "properties": { - "media_buy_count": { - "description": "Number of active media buys in the period", - "minimum": 0, - "type": "integer" - }, - "total_spend": { - "description": "Total spend in the period, in currency", - "minimum": 0, - "type": "number" - } - }, - "required": [ - "total_spend" - ], - "type": "object" + "context": { + "$ref": "../core/context.json" }, - "timezone": { - "description": "IANA timezone of the seller's billing day boundaries (e.g., 'America/New_York'). All dates in this response \u2014 period, invoice periods, due dates \u2014 are calendar dates in this timezone. Buyers in a different timezone should expect spend boundaries to differ from their own calendar day.", - "type": "string" + "ext": { + "$ref": "../core/ext.json" } }, "required": [ @@ -269,12 +186,37 @@ "period", "timezone" ], - "title": "GetAccountFinancialsSuccess", - "type": "object" + "additionalProperties": true, + "not": { + "required": [ + "errors" + ] + } }, { - "additionalProperties": true, + "title": "GetAccountFinancialsError", "description": "Operation failed \u2014 financials not available", + "type": "object", + "properties": { + "errors": { + "type": "array", + "description": "Operation-level errors", + "items": { + "$ref": "../core/error.json" + }, + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "errors" + ], + "additionalProperties": true, "not": { "anyOf": [ { @@ -298,30 +240,88 @@ ] } ] - }, - "properties": { - "context": { - "$ref": "../core/context.json" + } + } + ], + "examples": [ + { + "description": "Credit account \u2014 current, with invoice history", + "data": { + "account": { + "account_id": "acc_acme_001" }, - "errors": { - "description": "Operation-level errors", - "items": { - "$ref": "../core/error.json" + "currency": "USD", + "period": { + "start": "2026-02-01", + "end": "2026-02-28" + }, + "timezone": "America/New_York", + "spend": { + "total_spend": 45230.0, + "media_buy_count": 3 + }, + "credit": { + "credit_limit": 100000.0, + "available_credit": 54770.0, + "utilization_percent": 45.23 + }, + "payment_status": "current", + "payment_terms": "net_30", + "invoices": [ + { + "invoice_id": "inv_2026_01", + "period": { + "start": "2026-01-01", + "end": "2026-01-31" + }, + "amount": 38500.0, + "status": "paid", + "due_date": "2026-02-28", + "paid_date": "2026-02-15" + } + ] + } + }, + { + "description": "Prepay account with low balance", + "data": { + "account": { + "brand": { + "domain": "acme-corp.com" }, - "minItems": 1, - "type": "array" + "operator": "acme-corp.com" }, - "ext": { - "$ref": "../core/ext.json" - } - }, - "required": [ - "errors" - ], - "title": "GetAccountFinancialsError", - "type": "object" + "currency": "USD", + "period": { + "start": "2026-02-01", + "end": "2026-02-28" + }, + "timezone": "America/Los_Angeles", + "spend": { + "total_spend": 8200.0, + "media_buy_count": 2 + }, + "balance": { + "available": 1800.0, + "last_top_up": { + "amount": 10000.0, + "date": "2026-02-01" + } + }, + "payment_status": "current", + "payment_terms": "prepay" + } + }, + { + "description": "Agent-billed account \u2014 not supported", + "data": { + "errors": [ + { + "code": "UNSUPPORTED_FEATURE", + "message": "Financial data is not available for agent-billed accounts. The agent's own billing system is the source of truth." + } + ] + } } - ], - "title": "Get Account Financials Response", - "type": "object" + ] } \ No newline at end of file diff --git a/schemas/cache/account/list-accounts-request.json b/schemas/cache/account/list-accounts-request.json index 8cf254921..0d2dbe0f7 100644 --- a/schemas/cache/account/list-accounts-request.json +++ b/schemas/cache/account/list-accounts-request.json @@ -1,23 +1,17 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "List Accounts Request", "description": "Request parameters for listing accounts accessible to the authenticated agent", + "type": "object", "properties": { - "context": { - "$ref": "../core/context.json" - }, - "ext": { - "$ref": "../core/ext.json" - }, - "pagination": { - "$ref": "../core/pagination-request.json" - }, - "sandbox": { - "description": "Filter by sandbox status. true returns only sandbox accounts, false returns only production accounts. Omit to return all accounts. Primarily used with explicit accounts (require_operator_auth: true) where sandbox accounts are pre-existing test accounts on the platform.", - "type": "boolean" + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 }, "status": { - "description": "Filter accounts by status. Omit to return accounts in all statuses.", + "type": "string", "enum": [ "active", "pending_approval", @@ -26,10 +20,22 @@ "suspended", "closed" ], - "type": "string" + "description": "Filter accounts by status. Omit to return accounts in all statuses." + }, + "pagination": { + "$ref": "../core/pagination-request.json" + }, + "sandbox": { + "type": "boolean", + "description": "Filter by sandbox status. true returns only sandbox accounts, false returns only production accounts. Omit to return all accounts. Primarily used with explicit accounts (require_operator_auth: true) where sandbox accounts are pre-existing test accounts on the platform." + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" } }, "required": [], - "title": "List Accounts Request", - "type": "object" + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/account/list-accounts-response.json b/schemas/cache/account/list-accounts-response.json index 2afe44ecf..bd282efaf 100644 --- a/schemas/cache/account/list-accounts-response.json +++ b/schemas/cache/account/list-accounts-response.json @@ -1,48 +1,79 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "List Accounts Response", "description": "Response payload for list_accounts task", + "type": "object", + "properties": { + "accounts": { + "type": "array", + "description": "Array of accounts accessible to the authenticated agent", + "items": { + "$ref": "../core/account.json" + } + }, + "errors": { + "type": "array", + "description": "Task-specific errors and warnings", + "items": { + "$ref": "../core/error.json" + } + }, + "pagination": { + "$ref": "../core/pagination-response.json" + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "accounts" + ], + "additionalProperties": true, "examples": [ { + "description": "Agency with multiple client accounts", "data": { "accounts": [ { "account_id": "acc_acme_pinnacle", - "account_scope": "operator_brand", + "name": "Acme c/o Pinnacle", "advertiser": "Acme Corp", - "billing": "operator", "billing_proxy": "Pinnacle Media", "brand": { "domain": "acme-corp.com" }, - "name": "Acme c/o Pinnacle", "operator": "pinnacle-media.com", + "billing": "operator", + "account_scope": "operator_brand", "status": "active" }, { "account_id": "acc_nova_pinnacle", - "account_scope": "operator_brand", + "name": "Nova c/o Pinnacle", "advertiser": "Nova Brands", - "billing": "operator", "billing_proxy": "Pinnacle Media", "brand": { - "brand_id": "spark", - "domain": "nova-brands.com" + "domain": "nova-brands.com", + "brand_id": "spark" }, - "name": "Nova c/o Pinnacle", "operator": "pinnacle-media.com", + "billing": "operator", + "account_scope": "operator_brand", "status": "active" }, { "account_id": "acc_pinnacle", - "account_scope": "operator", + "name": "Pinnacle", "advertiser": "Pinnacle Media", - "billing": "operator", "brand": { "domain": "pinnacle-media.com" }, - "name": "Pinnacle", "operator": "pinnacle-media.com", + "billing": "operator", + "account_scope": "operator", "status": "active" } ], @@ -50,58 +81,27 @@ "has_more": false, "total_count": 3 } - }, - "description": "Agency with multiple client accounts" + } }, { + "description": "Direct advertiser with single account", "data": { "accounts": [ { "account_id": "acc_acme_direct", - "account_scope": "brand", + "name": "Acme", "advertiser": "Acme Corp", - "billing": "operator", "brand": { "domain": "acme-corp.com" }, - "name": "Acme", "operator": "acme-corp.com", - "rate_card": "acme_vip_2024", - "status": "active" + "billing": "operator", + "account_scope": "brand", + "status": "active", + "rate_card": "acme_vip_2024" } ] - }, - "description": "Direct advertiser with single account" + } } - ], - "properties": { - "accounts": { - "description": "Array of accounts accessible to the authenticated agent", - "items": { - "$ref": "../core/account.json" - }, - "type": "array" - }, - "context": { - "$ref": "../core/context.json" - }, - "errors": { - "description": "Task-specific errors and warnings", - "items": { - "$ref": "../core/error.json" - }, - "type": "array" - }, - "ext": { - "$ref": "../core/ext.json" - }, - "pagination": { - "$ref": "../core/pagination-response.json" - } - }, - "required": [ - "accounts" - ], - "title": "List Accounts Response", - "type": "object" + ] } \ No newline at end of file diff --git a/schemas/cache/account/report-usage-request.json b/schemas/cache/account/report-usage-request.json index 7146f5e09..09195b5bf 100644 --- a/schemas/cache/account/report-usage-request.json +++ b/schemas/cache/account/report-usage-request.json @@ -1,126 +1,81 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Report Usage Request", "description": "Reports how a vendor's service was consumed after campaign delivery. Used by orchestrators (DSPs, storefronts) to inform vendor agents (signals, governance, creative) what was used so the vendor can track earned revenue and verify billing. Records can span multiple accounts and campaigns in a single request.", - "examples": [ - { - "data": { - "idempotency_key": "550e8400-e29b-41d4-a716-446655440000", - "reporting_period": { - "end": "2025-03-31T23:59:59Z", - "start": "2025-03-01T00:00:00Z" - }, - "usage": [ - { - "account": { - "account_id": "acct_pinnacle_signals" - }, - "currency": "USD", - "impressions": 4200000, - "media_spend": 21000.0, - "pricing_option_id": "po_lux_auto_cpm", - "signal_agent_segment_id": "luxury_auto_intenders", - "vendor_cost": 2100.0 - } - ] - }, - "description": "Signal usage for a single campaign" - }, - { - "data": { - "reporting_period": { - "end": "2025-03-31T23:59:59Z", - "start": "2025-03-01T00:00:00Z" - }, - "usage": [ - { - "account": { - "account_id": "acct_pinnacle_signals" - }, - "currency": "USD", - "impressions": 2100000, - "pricing_option_id": "po_lux_auto_cpm", - "signal_agent_segment_id": "luxury_auto_intenders", - "vendor_cost": 1050.0 - }, - { - "account": { - "account_id": "acct_nova" - }, - "currency": "USD", - "impressions": 800000, - "pricing_option_id": "po_eco_cpm", - "signal_agent_segment_id": "eco_conscious_shoppers", - "vendor_cost": 400.0 - } - ] - }, - "description": "Multi-account batch across two campaigns" - } - ], + "type": "object", "properties": { - "context": { - "$ref": "../core/context.json" - }, - "ext": { - "$ref": "../core/ext.json" + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 }, "idempotency_key": { - "description": "Client-generated unique key for this request. If a request with the same key has already been accepted, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request. Prevents duplicate billing on retries.", - "type": "string" + "type": "string", + "description": "Client-generated unique key for this request. If a request with the same key has already been accepted, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request. Prevents duplicate billing on retries." }, "reporting_period": { "$ref": "../core/datetime-range.json", "description": "The time range covered by this usage report. Applies to all records in the request." }, "usage": { + "type": "array", "description": "One or more usage records. Each record is self-contained: it carries its own account, allowing a single request to span multiple accounts.", + "minItems": 1, "items": { - "additionalProperties": true, + "type": "object", "properties": { "account": { "$ref": "../core/account-ref.json", "description": "Account for this usage record." }, + "media_buy_id": { + "type": "string", + "description": "Seller-assigned media buy identifier. Links this usage record to a specific media buy." + }, + "vendor_cost": { + "type": "number", + "minimum": 0, + "description": "Amount owed to the vendor for this record, denominated in currency." + }, "currency": { - "description": "ISO 4217 currency code.", + "type": "string", "pattern": "^[A-Z]{3}$", - "type": "string" + "description": "ISO 4217 currency code." + }, + "pricing_option_id": { + "type": "string", + "description": "Pricing option identifier from the vendor's discovery response (e.g., get_signals, list_content_standards). The vendor uses this to verify the correct rate was applied." }, "impressions": { - "description": "Impressions delivered using this vendor service.", + "type": "integer", "minimum": 0, - "type": "integer" - }, - "media_buy_id": { - "description": "Seller-assigned media buy identifier. Links this usage record to a specific media buy.", - "type": "string" + "description": "Impressions delivered using this vendor service." }, "media_spend": { - "description": "Media spend in currency for the period. Required when a percent_of_media pricing model was used, so the vendor can verify the applied rate.", + "type": "number", "minimum": 0, - "type": "number" - }, - "pricing_option_id": { - "description": "Pricing option identifier from the vendor's discovery response (e.g., get_signals, list_content_standards). The vendor uses this to verify the correct rate was applied.", - "type": "string" - }, - "rights_id": { - "description": "Rights grant identifier from acquire_rights. Required for brand/rights agents. Links usage records to specific rights grants for cap tracking, billing verification, and overage calculation.", - "type": "string" + "description": "Media spend in currency for the period. Required when a percent_of_media pricing model was used, so the vendor can verify the applied rate." }, "signal_agent_segment_id": { - "description": "Signal identifier from get_signals. Required for signals agents.", - "type": "string" + "type": "string", + "description": "Signal identifier from get_signals. Required for signals agents." }, "standards_id": { - "description": "Content standards configuration identifier. Required for governance agents.", - "type": "string" + "type": "string", + "description": "Content standards configuration identifier. Required for governance agents." }, - "vendor_cost": { - "description": "Amount owed to the vendor for this record, denominated in currency.", - "minimum": 0, - "type": "number" + "rights_id": { + "type": "string", + "description": "Rights grant identifier from acquire_rights. Required for brand/rights agents. Links usage records to specific rights grants for cap tracking, billing verification, and overage calculation." + }, + "creative_id": { + "type": "string", + "description": "Creative identifier from build_creative or list_creatives. Required for creative agents. Links usage records to specific creatives for billing verification." + }, + "property_list_id": { + "type": "string", + "description": "Property list identifier from list_property_lists. Required for property list agents. Links usage records to specific property lists for billing verification." } }, "required": [ @@ -128,16 +83,77 @@ "vendor_cost", "currency" ], - "type": "object" - }, - "minItems": 1, - "type": "array" + "additionalProperties": true + } + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" } }, "required": [ + "idempotency_key", "reporting_period", "usage" ], - "title": "Report Usage Request", - "type": "object" + "additionalProperties": true, + "examples": [ + { + "description": "Signal usage for a single campaign", + "data": { + "idempotency_key": "550e8400-e29b-41d4-a716-446655440000", + "reporting_period": { + "start": "2025-03-01T00:00:00Z", + "end": "2025-03-31T23:59:59Z" + }, + "usage": [ + { + "account": { + "account_id": "acct_pinnacle_signals" + }, + "signal_agent_segment_id": "luxury_auto_intenders", + "pricing_option_id": "po_lux_auto_cpm", + "impressions": 4200000, + "media_spend": 21000, + "vendor_cost": 2100, + "currency": "USD" + } + ] + } + }, + { + "description": "Multi-account batch across two campaigns", + "data": { + "idempotency_key": "8b7a9c2d-3456-4789-abcd-ef0123456789", + "reporting_period": { + "start": "2025-03-01T00:00:00Z", + "end": "2025-03-31T23:59:59Z" + }, + "usage": [ + { + "account": { + "account_id": "acct_pinnacle_signals" + }, + "signal_agent_segment_id": "luxury_auto_intenders", + "pricing_option_id": "po_lux_auto_cpm", + "impressions": 2100000, + "vendor_cost": 1050, + "currency": "USD" + }, + { + "account": { + "account_id": "acct_nova" + }, + "signal_agent_segment_id": "eco_conscious_shoppers", + "pricing_option_id": "po_eco_cpm", + "impressions": 800000, + "vendor_cost": 400, + "currency": "USD" + } + ] + } + } + ] } \ No newline at end of file diff --git a/schemas/cache/account/report-usage-response.json b/schemas/cache/account/report-usage-response.json index 8a0fc81c0..1254d33dd 100644 --- a/schemas/cache/account/report-usage-response.json +++ b/schemas/cache/account/report-usage-response.json @@ -1,55 +1,55 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Report Usage Response", "description": "Response from report_usage. Partial acceptance is valid \u2014 records that pass validation are stored even when others fail.", - "examples": [ - { - "data": { - "accepted": 2 - }, - "description": "All records accepted" - }, - { - "data": { - "accepted": 1, - "errors": [ - { - "code": "INVALID_PRICING_OPTION", - "field": "usage[1].pricing_option_id", - "message": "pricing_option_id 'po_unknown' does not exist on this account" - } - ] - }, - "description": "Partial acceptance \u2014 one record failed validation" - } - ], + "type": "object", "properties": { "accepted": { - "description": "Number of usage records successfully stored.", + "type": "integer", "minimum": 0, - "type": "integer" - }, - "context": { - "$ref": "../core/context.json" + "description": "Number of usage records successfully stored." }, "errors": { + "type": "array", "description": "Validation errors for individual records. The field property identifies which record failed (e.g., 'usage[1].pricing_option_id').", "items": { "$ref": "../core/error.json" - }, - "type": "array" + } + }, + "sandbox": { + "type": "boolean", + "description": "When true, the account is a sandbox account and no billing occurred." + }, + "context": { + "$ref": "../core/context.json" }, "ext": { "$ref": "../core/ext.json" - }, - "sandbox": { - "description": "When true, the account is a sandbox account and no billing occurred.", - "type": "boolean" } }, "required": [ "accepted" ], - "title": "Report Usage Response", - "type": "object" + "additionalProperties": true, + "examples": [ + { + "description": "All records accepted", + "data": { + "accepted": 2 + } + }, + { + "description": "Partial acceptance \u2014 one record failed validation", + "data": { + "accepted": 1, + "errors": [ + { + "code": "INVALID_PRICING_OPTION", + "message": "pricing_option_id 'po_unknown' does not exist on this account", + "field": "usage[1].pricing_option_id" + } + ] + } + } + ] } \ No newline at end of file diff --git a/schemas/cache/account/sync-accounts-request.json b/schemas/cache/account/sync-accounts-request.json index 50145dfbf..5337f6195 100644 --- a/schemas/cache/account/sync-accounts-request.json +++ b/schemas/cache/account/sync-accounts-request.json @@ -1,190 +1,212 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Sync Accounts Request", "description": "Sync advertiser accounts with a seller using upsert semantics. The agent declares which brands it represents, who operates on each brand's behalf, and the billing model. The seller provisions or links accounts accordingly, returning per-account status.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "idempotency_key": { + "type": "string", + "description": "Client-generated unique key for at-most-once execution. Natural per-account upsert keys (brand, operator) handle resource-level dedup, but the envelope triggers onboarding webhooks, billing setup, and audit events \u2014 this key prevents those side effects from firing twice on retry. MUST be unique per (seller, request) pair. Use a fresh UUID v4 for each request.", + "minLength": 16, + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" + }, + "accounts": { + "type": "array", + "description": "Advertiser accounts to sync", + "items": { + "type": "object", + "description": "An advertiser account the agent wants to operate on the seller", + "properties": { + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Brand reference identifying the advertiser. Uses the brand's house domain and optional brand_id from brand.json." + }, + "operator": { + "type": "string", + "description": "Domain of the entity operating on the brand's behalf (e.g., 'pinnacle-media.com'). When the brand operates directly, this is the brand's domain. Verified against the brand's authorized_operators in brand.json.", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$" + }, + "billing": { + "type": "string", + "enum": [ + "operator", + "agent", + "advertiser" + ], + "description": "Who should be invoiced. operator: seller invoices the operator (agency or brand buying direct). agent: agent consolidates billing across brands. advertiser: seller invoices the advertiser directly, even when a different operator places orders on their behalf. The seller must either accept this billing model or reject the request." + }, + "billing_entity": { + "$ref": "../core/business-entity.json", + "description": "Business entity details for the party responsible for payment. The agent provides this so the seller has the legal name, tax IDs, address, and bank details needed for formal B2B invoicing." + }, + "payment_terms": { + "type": "string", + "enum": [ + "net_15", + "net_30", + "net_45", + "net_60", + "net_90", + "prepay" + ], + "description": "Payment terms for this account. The seller must either accept these terms or reject the account \u2014 terms are never silently remapped. When omitted, the seller applies its default terms." + }, + "sandbox": { + "type": "boolean", + "description": "When true, provision this as a sandbox account with no real platform calls or billing. Only applicable to implicit accounts (require_operator_auth: false). For explicit accounts, sandbox accounts are pre-existing test accounts discovered via list_accounts." + }, + "preferred_reporting_protocol": { + "$ref": "../enums/cloud-storage-protocol.json", + "description": "Buyer's preferred cloud storage protocol for offline reporting delivery. The seller provisions the account's reporting_bucket using this protocol if supported. When omitted, the seller chooses from its supported offline_delivery_protocols. Only meaningful when the seller's reporting_delivery_methods includes 'offline'." + } + }, + "required": [ + "brand", + "operator", + "billing" + ], + "additionalProperties": true + }, + "maxItems": 1000 + }, + "delete_missing": { + "type": "boolean", + "default": false, + "description": "When true, accounts previously synced by this agent but not included in this request will be deactivated. Scoped to the authenticated agent \u2014 does not affect accounts managed by other agents. Use with caution." + }, + "dry_run": { + "type": "boolean", + "default": false, + "description": "When true, preview what would change without applying. Returns what would be created/updated/deactivated." + }, + "push_notification_config": { + "$ref": "../core/push-notification-config.json", + "description": "Webhook for async notifications when account status changes (e.g., pending_approval transitions to active)." + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "idempotency_key", + "accounts" + ], + "additionalProperties": true, "examples": [ { + "description": "Agency syncing multiple advertisers with different billing", "data": { + "idempotency_key": "a7f9c2e4-1234-4567-89ab-cdef01234567", "accounts": [ { - "billing": "operator", "brand": { - "brand_id": "spark", - "domain": "nova-brands.com" + "domain": "nova-brands.com", + "brand_id": "spark" }, - "operator": "pinnacle-media.com" + "operator": "pinnacle-media.com", + "billing": "operator" }, { - "billing": "agent", "brand": { - "brand_id": "glow", - "domain": "nova-brands.com" + "domain": "nova-brands.com", + "brand_id": "glow" }, - "operator": "pinnacle-media.com" + "operator": "pinnacle-media.com", + "billing": "agent" } ] - }, - "description": "Agency syncing multiple advertisers with different billing" + } }, { + "description": "Brand buying direct with payment terms", "data": { + "idempotency_key": "b8e0d3f5-2345-4678-9abc-def012345678", "accounts": [ { - "billing": "operator", "brand": { "domain": "acme-corp.com" }, "operator": "acme-corp.com", + "billing": "operator", "payment_terms": "net_30" } ] - }, - "description": "Brand buying direct with payment terms" + } }, { + "description": "Agent consolidating billing with net-60 terms", "data": { + "idempotency_key": "c9f1e4a6-3456-4789-abcd-ef0123456789", "accounts": [ { - "billing": "agent", "brand": { - "brand_id": "spark", - "domain": "nova-brands.com" + "domain": "nova-brands.com", + "brand_id": "spark" }, "operator": "pinnacle-media.com", + "billing": "agent", "payment_terms": "net_60" }, { - "billing": "agent", "brand": { - "brand_id": "glow", - "domain": "nova-brands.com" + "domain": "nova-brands.com", + "brand_id": "glow" }, "operator": "pinnacle-media.com", + "billing": "agent", "payment_terms": "net_60" } ] - }, - "description": "Agent consolidating billing with net-60 terms" + } }, { + "description": "Advertiser billed directly with structured billing entity (DACH B2B)", "data": { + "idempotency_key": "d0a2f5b7-4567-489a-bcde-f01234567890", "accounts": [ { + "brand": { + "domain": "acme-corp.com" + }, + "operator": "pinnacle-media.com", "billing": "advertiser", "billing_entity": { + "legal_name": "Acme Corporation GmbH", + "vat_id": "DE987654321", + "registration_number": "HRB 67890", "address": { + "street": "Hauptstrasse 42", "city": "Munich", - "country": "DE", "postal_code": "80331", - "street": "Hauptstrasse 42" - }, - "bank": { - "account_holder": "Acme Corporation GmbH", - "bic": "SOLADEST600", - "iban": "DE75512108001245126199" + "country": "DE" }, "contacts": [ { - "email": "billing@acme-corp.com", + "role": "billing", "name": "AP Department", - "role": "billing" + "email": "billing@acme-corp.com" } ], - "legal_name": "Acme Corporation GmbH", - "registration_number": "HRB 67890", - "vat_id": "DE987654321" - }, - "brand": { - "domain": "acme-corp.com" + "bank": { + "account_holder": "Acme Corporation GmbH", + "iban": "DE75512108001245126199", + "bic": "SOLADEST600" + } }, - "operator": "pinnacle-media.com", "payment_terms": "net_30" } ] - }, - "description": "Advertiser billed directly with structured billing entity (DACH B2B)" + } } - ], - "properties": { - "accounts": { - "description": "Advertiser accounts to sync", - "items": { - "additionalProperties": true, - "description": "An advertiser account the agent wants to operate on the seller", - "properties": { - "billing": { - "description": "Who should be invoiced. operator: seller invoices the operator (agency or brand buying direct). agent: agent consolidates billing across brands. advertiser: seller invoices the advertiser directly, even when a different operator places orders on their behalf. The seller must either accept this billing model or reject the request.", - "enum": [ - "operator", - "agent", - "advertiser" - ], - "type": "string" - }, - "billing_entity": { - "$ref": "../core/business-entity.json", - "description": "Business entity details for the party responsible for payment. The agent provides this so the seller has the legal name, tax IDs, address, and bank details needed for formal B2B invoicing." - }, - "brand": { - "$ref": "../core/brand-ref.json", - "description": "Brand reference identifying the advertiser. Uses the brand's house domain and optional brand_id from brand.json." - }, - "operator": { - "description": "Domain of the entity operating on the brand's behalf (e.g., 'pinnacle-media.com'). When the brand operates directly, this is the brand's domain. Verified against the brand's authorized_operators in brand.json.", - "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", - "type": "string" - }, - "payment_terms": { - "description": "Payment terms for this account. The seller must either accept these terms or reject the account \u2014 terms are never silently remapped. When omitted, the seller applies its default terms.", - "enum": [ - "net_15", - "net_30", - "net_45", - "net_60", - "net_90", - "prepay" - ], - "type": "string" - }, - "sandbox": { - "description": "When true, provision this as a sandbox account with no real platform calls or billing. Only applicable to implicit accounts (require_operator_auth: false). For explicit accounts, sandbox accounts are pre-existing test accounts discovered via list_accounts.", - "type": "boolean" - } - }, - "required": [ - "brand", - "operator", - "billing" - ], - "type": "object" - }, - "maxItems": 1000, - "type": "array" - }, - "context": { - "$ref": "../core/context.json" - }, - "delete_missing": { - "default": false, - "description": "When true, accounts previously synced by this agent but not included in this request will be deactivated. Scoped to the authenticated agent \u2014 does not affect accounts managed by other agents. Use with caution.", - "type": "boolean" - }, - "dry_run": { - "default": false, - "description": "When true, preview what would change without applying. Returns what would be created/updated/deactivated.", - "type": "boolean" - }, - "ext": { - "$ref": "../core/ext.json" - }, - "push_notification_config": { - "$ref": "../core/push-notification-config.json", - "description": "Webhook for async notifications when account status changes (e.g., pending_approval transitions to active)." - } - }, - "required": [ - "accounts" - ], - "title": "Sync Accounts Request", - "type": "object" + ] } \ No newline at end of file diff --git a/schemas/cache/account/sync-accounts-response.json b/schemas/cache/account/sync-accounts-response.json index 82da86743..000ad803f 100644 --- a/schemas/cache/account/sync-accounts-response.json +++ b/schemas/cache/account/sync-accounts-response.json @@ -1,235 +1,115 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Sync Accounts Response", "description": "Response from account sync operation. Returns per-account results with status and billing, or operation-level errors on complete failure.", - "examples": [ - { - "data": { - "accounts": [ - { - "account_id": "acc_spark_001", - "account_scope": "operator_brand", - "action": "created", - "billing": "operator", - "brand": { - "brand_id": "spark", - "domain": "nova-brands.com" - }, - "name": "Spark (via Pinnacle)", - "operator": "pinnacle-media.com", - "status": "active" - }, - { - "account_id": "acc_glow_pending", - "account_scope": "operator_brand", - "action": "created", - "billing": "operator", - "brand": { - "brand_id": "glow", - "domain": "nova-brands.com" - }, - "name": "Glow", - "operator": "pinnacle-media.com", - "setup": { - "expires_at": "2026-03-10T00:00:00Z", - "message": "Complete advertiser registration and credit application", - "url": "https://seller.example.com/advertiser-onboard" - }, - "status": "pending_approval" - } - ] - }, - "description": "Mixed results \u2014 one active, one pending approval" - }, - { - "data": { - "accounts": [ - { - "action": "created", - "brand": { - "brand_id": "clearance", - "domain": "acme-corp.com" - }, - "operator": "acme-corp.com", - "status": "rejected", - "warnings": [ - "Account request declined: advertiser category not accepted on this platform." - ] - } - ] - }, - "description": "Rejected account \u2014 no account_id assigned" - }, - { - "data": { - "accounts": [ - { - "action": "failed", - "brand": { - "domain": "acme-corp.com" - }, - "errors": [ - { - "code": "BILLING_NOT_SUPPORTED", - "message": "Operator billing is not supported. This seller only accepts agent billing." - } - ], - "operator": "acme-corp.com", - "status": "rejected" - } - ] - }, - "description": "Unsupported billing \u2014 seller rejects the request" - }, - { - "data": { - "accounts": [ - { - "account_id": "acc_acme_direct_bill", - "account_scope": "operator_brand", - "action": "created", - "billing": "advertiser", - "billing_entity": { - "address": { - "city": "Munich", - "country": "DE", - "postal_code": "80331", - "street": "Hauptstrasse 42" - }, - "contacts": [ - { - "email": "billing@acme-corp.com", - "name": "AP Department", - "role": "billing" - } - ], - "legal_name": "Acme Corporation GmbH", - "registration_number": "HRB 67890", - "vat_id": "DE987654321" - }, - "brand": { - "domain": "acme-corp.com" - }, - "name": "Acme Corp (billed direct)", - "operator": "pinnacle-media.com", - "payment_terms": "net_30", - "status": "active" - } - ] - }, - "description": "Advertiser billed directly with billing entity (bank details omitted in response)" - }, - { - "data": { - "accounts": [ - { - "action": "failed", - "brand": { - "domain": "acme-corp.com" - }, - "errors": [ - { - "code": "PAYMENT_TERMS_NOT_SUPPORTED", - "message": "Net-60 payment terms are not available. Omit payment_terms to accept this seller's default terms (net_30)." - } - ], - "operator": "acme-corp.com", - "status": "rejected" - } - ] - }, - "description": "Unsupported payment terms \u2014 seller rejects the request" - } - ], + "type": "object", "oneOf": [ { - "additionalProperties": true, + "title": "SyncAccountsSuccess", "description": "Sync operation processed accounts (individual accounts may be pending or have action=failed)", - "not": { - "required": [ - "errors" - ] - }, + "type": "object", "properties": { + "dry_run": { + "type": "boolean", + "description": "Whether this was a dry run (no actual changes made)" + }, "accounts": { + "type": "array", "description": "Results for each account processed", "items": { - "additionalProperties": true, + "type": "object", "properties": { "account_id": { - "description": "Seller-assigned account identifier. Use this in subsequent create_media_buy and other account-scoped operations.", - "type": "string" + "type": "string", + "description": "Seller-assigned account identifier. Use this in subsequent create_media_buy and other account-scoped operations." }, - "account_scope": { - "description": "How the seller scoped this account. operator: shared across all brands for this operator. brand: shared across all operators for this brand. operator_brand: dedicated to this operator+brand pair. agent: the agent's default account.", - "enum": [ - "operator", - "brand", - "operator_brand", - "agent" - ], - "type": "string" + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Brand reference, echoed from the request" + }, + "operator": { + "type": "string", + "description": "Operator domain, echoed from request" + }, + "name": { + "type": "string", + "description": "Human-readable account name assigned by the seller" }, "action": { - "description": "Action taken for this account. created: new account provisioned. updated: existing account modified. unchanged: no changes needed. failed: could not process (see errors).", + "type": "string", "enum": [ "created", "updated", "unchanged", "failed" ], - "type": "string" + "description": "Action taken for this account. created: new account provisioned. updated: existing account modified. unchanged: no changes needed. failed: could not process (see errors)." + }, + "status": { + "type": "string", + "enum": [ + "active", + "pending_approval", + "rejected", + "payment_required", + "suspended", + "closed" + ], + "description": "Account status. active: ready for use. pending_approval: seller reviewing (credit, legal). rejected: seller declined the account request. payment_required: credit limit reached or funds depleted. suspended: was active, now paused. closed: was active, now terminated." }, "billing": { - "description": "Who is invoiced on this account. Matches the requested billing model.", + "type": "string", "enum": [ "operator", "agent", "advertiser" ], - "type": "string" + "description": "Who is invoiced on this account. Matches the requested billing model." }, "billing_entity": { "$ref": "../core/business-entity.json", "description": "Business entity details for the party responsible for payment, echoed from the request. Sellers MAY add fields the agent omitted (e.g., filling in registration_number from a credit check), but MUST NOT return data from a different entity. Bank details are omitted (write-only)." }, - "brand": { - "$ref": "../core/brand-ref.json", - "description": "Brand reference, echoed from the request" + "account_scope": { + "type": "string", + "enum": [ + "operator", + "brand", + "operator_brand", + "agent" + ], + "description": "How the seller scoped this account. operator: shared across all brands for this operator. brand: shared across all operators for this brand. operator_brand: dedicated to this operator+brand pair. agent: the agent's default account." }, - "credit_limit": { + "setup": { + "type": "object", + "description": "Setup information for pending accounts. Provides the agent (or human) with next steps to complete account activation.", "properties": { - "amount": { - "minimum": 0, - "type": "number" + "url": { + "type": "string", + "format": "uri", + "description": "URL where the human can complete the required action (credit application, legal agreement, add funds)" }, - "currency": { - "pattern": "^[A-Z]{3}$", - "type": "string" + "message": { + "type": "string", + "description": "Human-readable description of what's needed" + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "When this setup link expires" } }, "required": [ - "amount", - "currency" + "message" ], - "type": "object" + "additionalProperties": true }, - "errors": { - "description": "Per-account errors (only present when action is 'failed')", - "items": { - "$ref": "../core/error.json" - }, - "type": "array" - }, - "name": { - "description": "Human-readable account name assigned by the seller", - "type": "string" - }, - "operator": { - "description": "Operator domain, echoed from request", - "type": "string" + "rate_card": { + "type": "string", + "description": "Rate card applied to this account" }, "payment_terms": { - "description": "Payment terms agreed for this account. When the account is active, these are the binding terms for all invoices on this account.", + "type": "string", "enum": [ "net_15", "net_30", @@ -238,58 +118,42 @@ "net_90", "prepay" ], - "type": "string" + "description": "Payment terms agreed for this account. When the account is active, these are the binding terms for all invoices on this account." }, - "rate_card": { - "description": "Rate card applied to this account", - "type": "string" - }, - "sandbox": { - "description": "Whether this is a sandbox account, echoed from the request. Only present for implicit accounts.", - "type": "boolean" - }, - "setup": { - "additionalProperties": true, - "description": "Setup information for pending accounts. Provides the agent (or human) with next steps to complete account activation.", + "credit_limit": { + "type": "object", "properties": { - "expires_at": { - "description": "When this setup link expires", - "format": "date-time", - "type": "string" - }, - "message": { - "description": "Human-readable description of what's needed", - "type": "string" + "amount": { + "type": "number", + "minimum": 0 }, - "url": { - "description": "URL where the human can complete the required action (credit application, legal agreement, add funds)", - "format": "uri", - "type": "string" + "currency": { + "type": "string", + "pattern": "^[A-Z]{3}$" } }, "required": [ - "message" - ], - "type": "object" + "amount", + "currency" + ] }, - "status": { - "description": "Account status. active: ready for use. pending_approval: seller reviewing (credit, legal). rejected: seller declined the account request. payment_required: credit limit reached or funds depleted. suspended: was active, now paused. closed: was active, now terminated.", - "enum": [ - "active", - "pending_approval", - "rejected", - "payment_required", - "suspended", - "closed" - ], - "type": "string" + "errors": { + "type": "array", + "description": "Per-account errors (only present when action is 'failed')", + "items": { + "$ref": "../core/error.json" + } }, "warnings": { + "type": "array", "description": "Non-fatal warnings about this account", "items": { "type": "string" - }, - "type": "array" + } + }, + "sandbox": { + "type": "boolean", + "description": "Whether this is a sandbox account, echoed from the request. Only present for implicit accounts." } }, "required": [ @@ -298,17 +162,12 @@ "action", "status" ], - "type": "object" - }, - "type": "array" + "additionalProperties": true + } }, "context": { "$ref": "../core/context.json" }, - "dry_run": { - "description": "Whether this was a dry run (no actual changes made)", - "type": "boolean" - }, "ext": { "$ref": "../core/ext.json" } @@ -316,37 +175,28 @@ "required": [ "accounts" ], - "title": "SyncAccountsSuccess", - "type": "object" - }, - { "additionalProperties": true, - "description": "Operation failed completely, no accounts were processed", "not": { - "anyOf": [ - { - "required": [ - "accounts" - ] - }, - { - "required": [ - "dry_run" - ] - } + "required": [ + "errors" ] - }, + } + }, + { + "title": "SyncAccountsError", + "description": "Operation failed completely, no accounts were processed", + "type": "object", "properties": { - "context": { - "$ref": "../core/context.json" - }, "errors": { + "type": "array", "description": "Operation-level errors (e.g., authentication failure, service unavailable)", "items": { "$ref": "../core/error.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" }, "ext": { "$ref": "../core/ext.json" @@ -355,10 +205,160 @@ "required": [ "errors" ], - "title": "SyncAccountsError", - "type": "object" + "additionalProperties": true, + "not": { + "anyOf": [ + { + "required": [ + "accounts" + ] + }, + { + "required": [ + "dry_run" + ] + } + ] + } } ], - "title": "Sync Accounts Response", - "type": "object" + "examples": [ + { + "description": "Mixed results \u2014 one active, one pending approval", + "data": { + "accounts": [ + { + "account_id": "acc_spark_001", + "brand": { + "domain": "nova-brands.com", + "brand_id": "spark" + }, + "operator": "pinnacle-media.com", + "name": "Spark (via Pinnacle)", + "action": "created", + "status": "active", + "billing": "operator", + "account_scope": "operator_brand" + }, + { + "account_id": "acc_glow_pending", + "brand": { + "domain": "nova-brands.com", + "brand_id": "glow" + }, + "operator": "pinnacle-media.com", + "name": "Glow", + "action": "created", + "status": "pending_approval", + "billing": "operator", + "account_scope": "operator_brand", + "setup": { + "url": "https://seller.example.com/advertiser-onboard", + "message": "Complete advertiser registration and credit application", + "expires_at": "2026-03-10T00:00:00Z" + } + } + ] + } + }, + { + "description": "Rejected account \u2014 no account_id assigned", + "data": { + "accounts": [ + { + "brand": { + "domain": "acme-corp.com", + "brand_id": "clearance" + }, + "operator": "acme-corp.com", + "action": "created", + "status": "rejected", + "warnings": [ + "Account request declined: advertiser category not accepted on this platform." + ] + } + ] + } + }, + { + "description": "Unsupported billing \u2014 seller rejects the request", + "data": { + "accounts": [ + { + "brand": { + "domain": "acme-corp.com" + }, + "operator": "acme-corp.com", + "action": "failed", + "status": "rejected", + "errors": [ + { + "code": "BILLING_NOT_SUPPORTED", + "message": "Operator billing is not supported. This seller only accepts agent billing." + } + ] + } + ] + } + }, + { + "description": "Advertiser billed directly with billing entity (bank details omitted in response)", + "data": { + "accounts": [ + { + "account_id": "acc_acme_direct_bill", + "brand": { + "domain": "acme-corp.com" + }, + "operator": "pinnacle-media.com", + "name": "Acme Corp (billed direct)", + "action": "created", + "status": "active", + "billing": "advertiser", + "billing_entity": { + "legal_name": "Acme Corporation GmbH", + "vat_id": "DE987654321", + "registration_number": "HRB 67890", + "address": { + "street": "Hauptstrasse 42", + "city": "Munich", + "postal_code": "80331", + "country": "DE" + }, + "contacts": [ + { + "role": "billing", + "name": "AP Department", + "email": "billing@acme-corp.com" + } + ] + }, + "account_scope": "operator_brand", + "payment_terms": "net_30" + } + ] + } + }, + { + "description": "Unsupported payment terms \u2014 seller rejects the request", + "data": { + "accounts": [ + { + "brand": { + "domain": "acme-corp.com" + }, + "operator": "acme-corp.com", + "action": "failed", + "status": "rejected", + "errors": [ + { + "code": "PAYMENT_TERMS_NOT_SUPPORTED", + "message": "Net-60 payment terms are not available. Omit payment_terms to accept this seller's default terms (net_30)." + } + ] + } + ] + } + } + ] } \ No newline at end of file diff --git a/schemas/cache/account/sync-governance-request.json b/schemas/cache/account/sync-governance-request.json new file mode 100644 index 000000000..1162d45c5 --- /dev/null +++ b/schemas/cache/account/sync-governance-request.json @@ -0,0 +1,168 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Sync Governance Request", + "description": "Sync governance agent endpoints against specific accounts. The seller persists these governance agents and calls them for approval during media buy lifecycle events via check_governance. Uses replace semantics: each call replaces any previously synced agents on the specified accounts. The seller MUST verify that the authenticated agent has authority over each referenced account before persisting governance agents.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "idempotency_key": { + "type": "string", + "description": "Client-generated unique key for at-most-once execution. `account` gives resource-level dedup, but governance changes emit audit events and can trigger reapproval flows \u2014 this key prevents those side effects from firing twice on retry. MUST be unique per (seller, request) pair. Use a fresh UUID v4 for each request.", + "minLength": 16, + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" + }, + "accounts": { + "type": "array", + "description": "Per-account governance agent configuration. Each entry pairs an account reference with the governance agents for that account.", + "items": { + "type": "object", + "properties": { + "account": { + "$ref": "../core/account-ref.json", + "description": "Account to sync governance agents for. Use account_id for explicit accounts or brand + operator for implicit accounts." + }, + "governance_agents": { + "type": "array", + "description": "Governance agent endpoints for this account. The seller calls these agents via check_governance during media buy lifecycle events.", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "Governance agent endpoint URL. Must use HTTPS." + }, + "authentication": { + "type": "object", + "description": "Authentication the seller presents when calling this governance agent.", + "properties": { + "schemes": { + "type": "array", + "items": { + "$ref": "../enums/auth-scheme.json" + }, + "minItems": 1, + "maxItems": 1 + }, + "credentials": { + "type": "string", + "description": "Authentication credential (e.g., Bearer token).", + "minLength": 32 + } + }, + "required": [ + "schemes", + "credentials" + ], + "additionalProperties": false + }, + "categories": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "pattern": "^[a-z][a-z0-9_]*$" + }, + "description": "Governance categories this agent handles (e.g., ['budget_authority', 'strategic_alignment']). When omitted, the agent handles all categories.", + "maxItems": 20 + } + }, + "required": [ + "url", + "authentication" + ], + "additionalProperties": false + }, + "minItems": 1, + "maxItems": 10 + } + }, + "required": [ + "account", + "governance_agents" + ], + "additionalProperties": false + }, + "minItems": 1, + "maxItems": 100 + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "idempotency_key", + "accounts" + ], + "additionalProperties": true, + "examples": [ + { + "description": "Sync governance agents on explicit accounts (by account_id)", + "data": { + "idempotency_key": "e1b3a6c8-5678-489a-bcde-f01234567891", + "accounts": [ + { + "account": { + "account_id": "acct-social-001" + }, + "governance_agents": [ + { + "url": "https://governance.pinnacle-media.com/budget", + "authentication": { + "schemes": [ + "Bearer" + ], + "credentials": "gov-token-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, + "categories": [ + "budget_authority" + ] + } + ] + } + ] + } + }, + { + "description": "Sync governance agents on implicit accounts (by brand + operator)", + "data": { + "idempotency_key": "f2c4b7d9-6789-489b-cdef-012345678902", + "accounts": [ + { + "account": { + "brand": { + "domain": "nova-brands.com", + "brand_id": "spark" + }, + "operator": "pinnacle-media.com" + }, + "governance_agents": [ + { + "url": "https://governance.pinnacle-media.com/compliance", + "authentication": { + "schemes": [ + "Bearer" + ], + "credentials": "gov-token-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" + }, + "categories": [ + "geo_compliance" + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/schemas/cache/account/sync-governance-response.json b/schemas/cache/account/sync-governance-response.json new file mode 100644 index 000000000..7e20d597d --- /dev/null +++ b/schemas/cache/account/sync-governance-response.json @@ -0,0 +1,192 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Sync Governance Response", + "description": "Response from governance agent sync. Returns per-account results confirming sync, or operation-level errors on complete failure.", + "type": "object", + "oneOf": [ + { + "title": "SyncGovernanceSuccess", + "description": "Sync processed \u2014 individual accounts may have errors", + "type": "object", + "properties": { + "accounts": { + "type": "array", + "description": "Per-account sync results", + "items": { + "type": "object", + "properties": { + "account": { + "$ref": "../core/account-ref.json", + "description": "Account reference, echoed from request" + }, + "status": { + "type": "string", + "enum": [ + "synced", + "failed" + ], + "description": "Sync result. synced: governance agents persisted. failed: could not complete (see errors)." + }, + "governance_agents": { + "type": "array", + "description": "Governance agents now synced on this account. Reflects the persisted state after sync.", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "Governance agent endpoint URL." + }, + "categories": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "pattern": "^[a-z][a-z0-9_]*$" + }, + "description": "Governance categories this agent handles.", + "maxItems": 20 + } + }, + "required": [ + "url" + ], + "additionalProperties": false + } + }, + "errors": { + "type": "array", + "description": "Per-account errors (only present when status is 'failed')", + "items": { + "$ref": "../core/error.json" + } + } + }, + "required": [ + "account", + "status" + ], + "additionalProperties": true + } + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "accounts" + ], + "additionalProperties": true, + "not": { + "required": [ + "errors" + ] + } + }, + { + "title": "SyncGovernanceError", + "description": "Operation failed completely, no accounts were processed", + "type": "object", + "properties": { + "errors": { + "type": "array", + "description": "Operation-level errors (e.g., authentication failure, service unavailable)", + "items": { + "$ref": "../core/error.json" + }, + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "errors" + ], + "additionalProperties": true, + "not": { + "required": [ + "accounts" + ] + } + } + ], + "examples": [ + { + "description": "Governance agents synced on two accounts", + "data": { + "accounts": [ + { + "account": { + "account_id": "acct-social-001" + }, + "status": "synced", + "governance_agents": [ + { + "url": "https://governance.pinnacle-media.com/budget", + "categories": [ + "budget_authority" + ] + } + ] + }, + { + "account": { + "account_id": "acct-social-002" + }, + "status": "synced", + "governance_agents": [ + { + "url": "https://governance.pinnacle-media.com/compliance", + "categories": [ + "geo_compliance" + ] + } + ] + } + ] + } + }, + { + "description": "Partial failure \u2014 one account not found", + "data": { + "accounts": [ + { + "account": { + "account_id": "acct-social-001" + }, + "status": "synced", + "governance_agents": [ + { + "url": "https://governance.pinnacle-media.com/budget", + "categories": [ + "budget_authority" + ] + } + ] + }, + { + "account": { + "account_id": "acct-unknown" + }, + "status": "failed", + "errors": [ + { + "code": "ACCOUNT_NOT_FOUND", + "message": "Account 'acct-unknown' does not exist or is not accessible to the authenticated agent." + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/schemas/cache/adagents.json b/schemas/cache/adagents.json index ecbd6def0..5d5ee763c 100644 --- a/schemas/cache/adagents.json +++ b/schemas/cache/adagents.json @@ -1,574 +1,258 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AdCP Agents Authorization", "description": "Declaration of authorized agents for advertising inventory and data signals. Hosted at /.well-known/adagents.json on publisher domains (for properties) or data provider domains (for signals). Can either contain the full structure inline or reference an authoritative URL.", - "examples": [ - { - "$schema": "/schemas/3.0.0-rc.3/adagents.json", - "authoritative_location": "https://cdn.example.com/adagents/v2/adagents.json", - "last_updated": "2025-01-15T10:00:00Z" - }, + "oneOf": [ { - "$schema": "/schemas/3.0.0-rc.3/adagents.json", - "authorized_agents": [ - { - "authorization_type": "property_tags", - "authorized_for": "Official sales agent", - "countries": [ - "US", - "CA" - ], - "delegation_type": "direct", - "effective_from": "2025-01-01T00:00:00Z", - "exclusive": true, - "placement_ids": [ - "homepage_banner" - ], - "property_tags": [ - "all" - ], - "url": "https://agent.example.com" - } - ], - "last_updated": "2025-01-10T12:00:00Z", - "placement_tags": { - "display": { - "description": "Standard display placements", - "name": "Display" + "type": "object", + "description": "URL reference variant - points to the authoritative location of the adagents.json file", + "properties": { + "$schema": { + "type": "string", + "description": "JSON Schema identifier for this adagents.json file" }, - "homepage": { - "description": "Placements that render on the homepage", - "name": "Homepage" + "authoritative_location": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "HTTPS URL of the authoritative adagents.json file. When present, this file is a reference and the authoritative location contains the actual agent authorization data. Because one deploy can change authorization across every publisher in the network, validators MUST cap response size, refuse redirects on the fetch, enforce short timeouts, and serve the previously cached file on transient 5xx. See docs/governance/property/managed-networks#security-considerations." }, - "premium": { - "description": "Premium monetization placements", - "name": "Premium" + "last_updated": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 timestamp indicating when this reference was last updated" } }, - "placements": [ - { - "format_ids": [ - { - "agent_url": "https://creative.example.com", - "id": "display_728x90" - } - ], - "name": "Homepage Banner", - "placement_id": "homepage_banner", - "property_ids": [ - "example_site" - ], - "tags": [ - "homepage", - "display", - "premium" - ] - } - ], - "properties": [ - { - "identifiers": [ - { - "type": "domain", - "value": "example.com" - } - ], - "name": "Example Site", - "property_id": "example_site", - "property_type": "website", - "publisher_domain": "example.com" - } + "required": [ + "authoritative_location" ], - "tags": { - "all": { - "description": "All properties in this file", - "name": "All Properties" - } - } + "additionalProperties": true }, { - "$schema": "/schemas/3.0.0-rc.3/adagents.json", - "authorized_agents": [ - { - "authorization_type": "property_tags", - "authorized_for": "All Meta properties", - "property_tags": [ - "meta_network" - ], - "url": "https://meta-ads.com" - } - ], - "contact": { - "domain": "meta.com", - "email": "adops@meta.com", - "name": "Meta Advertising Operations", - "privacy_policy_url": "https://www.meta.com/privacy/policy", - "seller_id": "pub-meta-12345", - "tag_id": "12345" - }, - "last_updated": "2025-01-10T15:30:00Z", - "properties": [ - { - "identifiers": [ - { - "type": "ios_bundle", - "value": "com.burbn.instagram" - }, - { - "type": "android_package", - "value": "com.instagram.android" - } - ], - "name": "Instagram", - "property_type": "mobile_app", - "publisher_domain": "instagram.com", - "supported_channels": [ - "social", - "display", - "olv" - ], - "tags": [ - "meta_network", - "social_media" - ] + "type": "object", + "description": "Inline structure variant - contains full agent authorization data", + "properties": { + "$schema": { + "type": "string", + "description": "JSON Schema identifier for this adagents.json file" }, - { - "identifiers": [ - { - "type": "ios_bundle", - "value": "com.facebook.Facebook" + "contact": { + "type": "object", + "description": "Contact information for the entity managing this adagents.json file (may be publisher or third-party operator)", + "properties": { + "name": { + "type": "string", + "description": "Name of the entity managing this file (e.g., 'Meta Advertising Operations', 'Clear Channel Digital')", + "minLength": 1, + "maxLength": 255 }, - { - "type": "android_package", - "value": "com.facebook.katana" - } - ], - "name": "Facebook", - "property_type": "mobile_app", - "publisher_domain": "facebook.com", - "supported_channels": [ - "social", - "display", - "olv" - ], - "tags": [ - "meta_network", - "social_media" - ] - }, - { - "identifiers": [ - { - "type": "ios_bundle", - "value": "net.whatsapp.WhatsApp" + "email": { + "type": "string", + "format": "email", + "description": "Contact email for questions or issues with this authorization file", + "minLength": 1, + "maxLength": 255 }, - { - "type": "android_package", - "value": "com.whatsapp" + "domain": { + "type": "string", + "description": "Primary domain of the entity managing this file", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$" + }, + "seller_id": { + "type": "string", + "description": "Seller ID from IAB Tech Lab sellers.json (if applicable)", + "minLength": 1, + "maxLength": 255 + }, + "tag_id": { + "type": "string", + "description": "TAG Certified Against Fraud ID for verification (if applicable)", + "minLength": 1, + "maxLength": 100 + }, + "privacy_policy_url": { + "type": "string", + "format": "uri", + "description": "URL to the entity's privacy policy. Used for consumer consent flows when interacting with this sales agent." } + }, + "required": [ + "name" ], - "name": "WhatsApp", - "property_type": "mobile_app", - "publisher_domain": "whatsapp.com", - "supported_channels": [ - "social", - "display" - ], - "tags": [ - "meta_network", - "messaging" - ] - } - ], - "tags": { - "messaging": { - "description": "Messaging and communication apps", - "name": "Messaging Apps" + "additionalProperties": true }, - "meta_network": { - "description": "All Meta-owned properties", - "name": "Meta Network" + "properties": { + "type": "array", + "description": "Array of all properties covered by this adagents.json file. Defines the canonical property list that authorized agents reference.", + "items": { + "$ref": "core/property.json" + }, + "minItems": 1 }, - "social_media": { - "description": "Social networking applications", - "name": "Social Media Apps" - } - } - }, - { - "$schema": "/schemas/3.0.0-rc.3/adagents.json", - "authorized_agents": [ - { - "authorization_type": "property_tags", - "authorized_for": "Tumblr corporate properties only", - "property_tags": [ - "corporate" - ], - "url": "https://tumblr-sales.com" - } - ], - "contact": { - "name": "Tumblr Advertising" - }, - "last_updated": "2025-01-10T16:00:00Z", - "properties": [ - { - "identifiers": [ - { - "type": "domain", - "value": "tumblr.com" - } - ], - "name": "Tumblr Corporate", - "property_type": "website", - "publisher_domain": "tumblr.com", - "tags": [ - "corporate" - ] - } - ], - "tags": { - "corporate": { - "description": "Tumblr-owned corporate properties (not user blogs)", - "name": "Corporate Properties" - } - } - }, - { - "$schema": "/schemas/3.0.0-rc.3/adagents.json", - "authorized_agents": [ - { - "authorization_type": "publisher_properties", - "authorized_for": "CNN CTV properties via publisher authorization", - "publisher_properties": [ - { - "property_ids": [ - "cnn_ctv_app" - ], - "publisher_domain": "cnn.com", - "selection_type": "by_id" - } - ], - "url": "https://agent.example/api" + "collections": { + "type": "array", + "description": "Collections produced or distributed by this publisher. Declares the content programs whose inventory is sold through authorized agents. Products in get_products responses reference these collections by collection_id.", + "items": { + "$ref": "core/collection.json" + } }, - { - "authorization_type": "publisher_properties", - "authorized_for": "All CTV properties from multiple publishers", - "publisher_properties": [ - { - "property_tags": [ - "ctv" - ], - "publisher_domain": "cnn.com", - "selection_type": "by_tag" - }, - { - "property_tags": [ - "ctv" - ], - "publisher_domain": "espn.com", - "selection_type": "by_tag" - } - ], - "url": "https://agent.example/api" - } - ], - "contact": { - "domain": "agent.example", - "email": "sales@agent.example", - "name": "Example Third-Party Sales Agent" - }, - "last_updated": "2025-01-10T17:00:00Z" - }, - { - "$schema": "/schemas/3.0.0-rc.3/adagents.json", - "authorized_agents": [ - { - "authorization_type": "property_tags", - "authorized_for": "All news properties", - "property_tags": [ - "news" - ], - "url": "https://sales.news.example.com" - } - ], - "contact": { - "domain": "news.example.com", - "email": "adops@news.example.com", - "name": "Premium News Publisher" - }, - "last_updated": "2025-01-10T18:00:00Z", - "properties": [ - { - "identifiers": [ - { - "type": "domain", - "value": "news.example.com" - } - ], - "name": "News Example", - "property_type": "website", - "publisher_domain": "news.example.com", - "tags": [ - "premium", - "news" - ] - } - ], - "property_features": [ - { - "features": [ - "carbon_score", - "sustainability_grade" - ], - "name": "Scope3", - "publisher_id": "pub_news_12345", - "url": "https://api.scope3.com" - }, - { - "features": [ - "tag_certified_against_fraud", - "tag_brand_safety_certified" - ], - "name": "TAG", - "url": "https://api.tagtoday.net" - }, - { - "features": [ - "gdpr_compliant", - "tcf_registered", - "ccpa_compliant" - ], - "name": "OneTrust", - "publisher_id": "ot_news_67890", - "url": "https://api.onetrust.com" - } - ], - "tags": { - "news": { - "description": "News and journalism content", - "name": "News Properties" - }, - "premium": { - "description": "High-quality, brand-safe properties", - "name": "Premium Properties" - } - } - }, - { - "$schema": "/schemas/3.0.0-rc.3/adagents.json", - "authorized_agents": [ - { - "authorization_type": "signal_tags", - "authorized_for": "All Polk automotive signals via LiveRamp", - "signal_tags": [ - "automotive" - ], - "url": "https://liveramp.com/.well-known/adcp/signals" - }, - { - "authorization_type": "signal_ids", - "authorized_for": "Polk premium signals only", - "signal_ids": [ - "likely_tesla_buyers" - ], - "url": "https://the-trade-desk.com/.well-known/adcp/signals" - } - ], - "contact": { - "domain": "polk.com", - "email": "partnerships@polk.com", - "name": "Polk Automotive Data" - }, - "last_updated": "2025-01-15T10:00:00Z", - "signal_tags": { - "automotive": { - "description": "Vehicle-related audience segments", - "name": "Automotive Signals" - }, - "premium": { - "description": "High-value premium audience segments", - "name": "Premium Signals" - } - }, - "signals": [ - { - "category": "purchase_intent", - "description": "Consumers modeled as likely to purchase a Tesla in the next 12 months based on vehicle registration, financial, and behavioral data", - "id": "likely_tesla_buyers", - "name": "Likely Tesla Buyers", - "tags": [ - "automotive", - "premium" - ], - "value_type": "binary" - }, - { - "allowed_values": [ - "tesla", - "bmw", - "mercedes", - "audi", - "lexus", - "other_luxury", - "non_luxury" - ], - "category": "ownership", - "description": "Current vehicle make owned by the consumer", - "id": "vehicle_ownership", - "name": "Current Vehicle Ownership", - "tags": [ - "automotive" - ], - "value_type": "categorical" - }, - { - "category": "purchase_intent", - "description": "Likelihood score of purchasing any new vehicle in the next 6 months", - "id": "purchase_propensity", - "name": "Auto Purchase Propensity", - "range": { - "max": 1, - "min": 0, - "unit": "score" + "placements": { + "type": "array", + "description": "Canonical placement definitions for properties in this file. Products SHOULD reuse these placement_id values when exposing inventory in get_products, and authorized agents can scope authorization to these placement IDs.", + "items": { + "$ref": "core/placement-definition.json" }, - "tags": [ - "automotive" - ], - "value_type": "numeric" - } - ] - } - ], - "oneOf": [ - { - "additionalProperties": true, - "description": "URL reference variant - points to the authoritative location of the adagents.json file", - "properties": { - "$schema": { - "description": "JSON Schema identifier for this adagents.json file", - "type": "string" + "minItems": 1 }, - "authoritative_location": { - "description": "HTTPS URL of the authoritative adagents.json file. When present, this file is a reference and the authoritative location contains the actual agent authorization data.", - "format": "uri", - "pattern": "^https://", - "type": "string" + "tags": { + "type": "object", + "description": "Metadata for each tag referenced by properties. Provides human-readable context for property tag values.", + "additionalProperties": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for this tag" + }, + "description": { + "type": "string", + "description": "Description of what this tag represents" + } + }, + "required": [ + "name", + "description" + ], + "additionalProperties": true + } }, - "last_updated": { - "description": "ISO 8601 timestamp indicating when this reference was last updated", - "format": "date-time", - "type": "string" - } - }, - "required": [ - "authoritative_location" - ], - "type": "object" - }, - { - "additionalProperties": true, - "description": "Inline structure variant - contains full agent authorization data", - "properties": { - "$schema": { - "description": "JSON Schema identifier for this adagents.json file", - "type": "string" + "placement_tags": { + "type": "object", + "description": "Metadata for each tag referenced by placements. Provides human-readable context for publisher-defined placement tag values used in grouping and authorization.", + "additionalProperties": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Human-readable name for this placement tag" + }, + "description": { + "type": "string", + "description": "Description of what this placement tag represents" + } + }, + "required": [ + "name", + "description" + ], + "additionalProperties": true + } }, "authorized_agents": { + "type": "array", "description": "Array of sales agents authorized to make inventory from this file available to buyers. Authorization can be scoped to specific properties, collections, countries, and time windows, with optional delegation metadata indicating whether the path is direct, delegated, or network-mediated.", "items": { "oneOf": [ { - "additionalProperties": true, + "type": "object", "properties": { - "authorization_type": { - "const": "property_ids", - "description": "Discriminator indicating authorization by specific property IDs", - "type": "string" + "url": { + "type": "string", + "format": "uri", + "description": "The authorized agent's API endpoint URL" }, "authorized_for": { + "type": "string", "description": "Human-readable description of what this agent is authorized to sell", - "maxLength": 500, "minLength": 1, - "type": "string" + "maxLength": 500 + }, + "authorization_type": { + "type": "string", + "const": "property_ids", + "description": "Discriminator indicating authorization by specific property IDs" + }, + "property_ids": { + "type": "array", + "description": "Property IDs this agent is authorized for. Resolved against the top-level properties array in this file", + "items": { + "$ref": "core/property-id.json" + }, + "minItems": 1 }, "collections": { + "type": "array", "description": "Optional collection constraints. When present, authorization only applies to inventory associated with these collections.", "items": { "$ref": "core/collection-selector.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "countries": { - "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", + "placement_ids": { + "type": "array", + "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", "items": { - "pattern": "^[A-Z]{2}$", "type": "string" }, - "minItems": 1, + "minItems": 1 + }, + "placement_tags": { "type": "array", + "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "items": { + "type": "string" + }, + "minItems": 1, "uniqueItems": true }, "delegation_type": { - "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint.", + "type": "string", "enum": [ "direct", "delegated", "ad_network" ], - "type": "string" - }, - "effective_from": { - "description": "Optional start time for this authorization window.", - "format": "date-time", - "type": "string" - }, - "effective_until": { - "description": "Optional end time for this authorization window.", - "format": "date-time", - "type": "string" + "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint." }, "exclusive": { - "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory.", - "type": "boolean" - }, - "placement_ids": { - "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" + "type": "boolean", + "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory." }, - "placement_tags": { - "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "countries": { + "type": "array", + "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", "items": { - "type": "string" + "type": "string", + "pattern": "^[A-Z]{2}$" }, "minItems": 1, - "type": "array", "uniqueItems": true }, - "property_ids": { - "description": "Property IDs this agent is authorized for. Resolved against the top-level properties array in this file", - "items": { - "$ref": "core/property-id.json" - }, - "minItems": 1, - "type": "array" + "effective_from": { + "type": "string", + "format": "date-time", + "description": "Optional start time for this authorization window." + }, + "effective_until": { + "type": "string", + "format": "date-time", + "description": "Optional end time for this authorization window." }, "signing_keys": { + "type": "array", "description": "Optional publisher-attested public signing keys for this agent. Use these as the trust anchor for verifying signed agent responses instead of relying on key discovery from the agent domain alone.", "items": { "$ref": "core/agent-signing-key.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "url": { - "description": "The authorized agent's API endpoint URL", - "format": "uri", - "type": "string" + "encryption_keys": { + "type": "array", + "description": "X25519 public keys for TMPX exposure token encryption. Each key identifies a cluster master that can decrypt TMPX tokens. Used with HPKE mode_base \u2014 read replicas encrypt with this public key, only the master can decrypt.", + "items": { + "$ref": "core/agent-encryption-key.json" + }, + "minItems": 1 } }, "required": [ @@ -577,100 +261,108 @@ "authorization_type", "property_ids" ], - "type": "object" + "additionalProperties": true }, { - "additionalProperties": true, + "type": "object", "properties": { - "authorization_type": { - "const": "property_tags", - "description": "Discriminator indicating authorization by property tags", - "type": "string" + "url": { + "type": "string", + "format": "uri", + "description": "The authorized agent's API endpoint URL" }, "authorized_for": { + "type": "string", "description": "Human-readable description of what this agent is authorized to sell", - "maxLength": 500, "minLength": 1, - "type": "string" + "maxLength": 500 + }, + "authorization_type": { + "type": "string", + "const": "property_tags", + "description": "Discriminator indicating authorization by property tags" + }, + "property_tags": { + "type": "array", + "description": "Tags identifying which properties this agent is authorized for. Resolved against the top-level properties array in this file using tag matching", + "items": { + "$ref": "core/property-tag.json" + }, + "minItems": 1 }, "collections": { + "type": "array", "description": "Optional collection constraints. When present, authorization only applies to inventory associated with these collections.", "items": { "$ref": "core/collection-selector.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "countries": { - "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", + "placement_ids": { + "type": "array", + "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", "items": { - "pattern": "^[A-Z]{2}$", "type": "string" }, - "minItems": 1, + "minItems": 1 + }, + "placement_tags": { "type": "array", + "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "items": { + "type": "string" + }, + "minItems": 1, "uniqueItems": true }, "delegation_type": { - "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint.", + "type": "string", "enum": [ "direct", "delegated", "ad_network" ], - "type": "string" - }, - "effective_from": { - "description": "Optional start time for this authorization window.", - "format": "date-time", - "type": "string" - }, - "effective_until": { - "description": "Optional end time for this authorization window.", - "format": "date-time", - "type": "string" + "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint." }, "exclusive": { - "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory.", - "type": "boolean" - }, - "placement_ids": { - "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" + "type": "boolean", + "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory." }, - "placement_tags": { - "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "countries": { + "type": "array", + "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", "items": { - "type": "string" + "type": "string", + "pattern": "^[A-Z]{2}$" }, "minItems": 1, - "type": "array", "uniqueItems": true }, - "property_tags": { - "description": "Tags identifying which properties this agent is authorized for. Resolved against the top-level properties array in this file using tag matching", - "items": { - "$ref": "core/property-tag.json" - }, - "minItems": 1, - "type": "array" + "effective_from": { + "type": "string", + "format": "date-time", + "description": "Optional start time for this authorization window." + }, + "effective_until": { + "type": "string", + "format": "date-time", + "description": "Optional end time for this authorization window." }, "signing_keys": { + "type": "array", "description": "Optional publisher-attested public signing keys for this agent. Use these as the trust anchor for verifying signed agent responses instead of relying on key discovery from the agent domain alone.", "items": { "$ref": "core/agent-signing-key.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "url": { - "description": "The authorized agent's API endpoint URL", - "format": "uri", - "type": "string" + "encryption_keys": { + "type": "array", + "description": "X25519 public keys for TMPX exposure token encryption. Each key identifies a cluster master that can decrypt TMPX tokens. Used with HPKE mode_base \u2014 read replicas encrypt with this public key, only the master can decrypt.", + "items": { + "$ref": "core/agent-encryption-key.json" + }, + "minItems": 1 } }, "required": [ @@ -679,100 +371,108 @@ "authorization_type", "property_tags" ], - "type": "object" + "additionalProperties": true }, { - "additionalProperties": true, + "type": "object", "properties": { - "authorization_type": { - "const": "inline_properties", - "description": "Discriminator indicating authorization by inline property definitions", - "type": "string" + "url": { + "type": "string", + "format": "uri", + "description": "The authorized agent's API endpoint URL" }, "authorized_for": { + "type": "string", "description": "Human-readable description of what this agent is authorized to sell", - "maxLength": 500, "minLength": 1, - "type": "string" + "maxLength": 500 + }, + "authorization_type": { + "type": "string", + "const": "inline_properties", + "description": "Discriminator indicating authorization by inline property definitions" + }, + "properties": { + "type": "array", + "description": "Specific properties this agent is authorized for (alternative to property_ids/property_tags)", + "items": { + "$ref": "core/property.json" + }, + "minItems": 1 }, "collections": { + "type": "array", "description": "Optional collection constraints. When present, authorization only applies to inventory associated with these collections.", "items": { "$ref": "core/collection-selector.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "countries": { - "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", + "placement_ids": { + "type": "array", + "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", "items": { - "pattern": "^[A-Z]{2}$", "type": "string" }, - "minItems": 1, + "minItems": 1 + }, + "placement_tags": { "type": "array", + "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "items": { + "type": "string" + }, + "minItems": 1, "uniqueItems": true }, "delegation_type": { - "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint.", + "type": "string", "enum": [ "direct", "delegated", "ad_network" ], - "type": "string" - }, - "effective_from": { - "description": "Optional start time for this authorization window.", - "format": "date-time", - "type": "string" - }, - "effective_until": { - "description": "Optional end time for this authorization window.", - "format": "date-time", - "type": "string" + "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint." }, "exclusive": { - "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory.", - "type": "boolean" - }, - "placement_ids": { - "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" + "type": "boolean", + "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory." }, - "placement_tags": { - "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "countries": { + "type": "array", + "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", "items": { - "type": "string" + "type": "string", + "pattern": "^[A-Z]{2}$" }, "minItems": 1, - "type": "array", "uniqueItems": true }, - "properties": { - "description": "Specific properties this agent is authorized for (alternative to property_ids/property_tags)", - "items": { - "$ref": "core/property.json" - }, - "minItems": 1, - "type": "array" + "effective_from": { + "type": "string", + "format": "date-time", + "description": "Optional start time for this authorization window." + }, + "effective_until": { + "type": "string", + "format": "date-time", + "description": "Optional end time for this authorization window." }, "signing_keys": { + "type": "array", "description": "Optional publisher-attested public signing keys for this agent. Use these as the trust anchor for verifying signed agent responses instead of relying on key discovery from the agent domain alone.", "items": { "$ref": "core/agent-signing-key.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "url": { - "description": "The authorized agent's API endpoint URL", - "format": "uri", - "type": "string" + "encryption_keys": { + "type": "array", + "description": "X25519 public keys for TMPX exposure token encryption. Each key identifies a cluster master that can decrypt TMPX tokens. Used with HPKE mode_base \u2014 read replicas encrypt with this public key, only the master can decrypt.", + "items": { + "$ref": "core/agent-encryption-key.json" + }, + "minItems": 1 } }, "required": [ @@ -781,100 +481,108 @@ "authorization_type", "properties" ], - "type": "object" + "additionalProperties": true }, { - "additionalProperties": true, + "type": "object", "properties": { - "authorization_type": { - "const": "publisher_properties", - "description": "Discriminator indicating authorization for properties from other publisher domains", - "type": "string" + "url": { + "type": "string", + "format": "uri", + "description": "The authorized agent's API endpoint URL" }, "authorized_for": { + "type": "string", "description": "Human-readable description of what this agent is authorized to sell", - "maxLength": 500, "minLength": 1, - "type": "string" + "maxLength": 500 + }, + "authorization_type": { + "type": "string", + "const": "publisher_properties", + "description": "Discriminator indicating authorization for properties from other publisher domains" + }, + "publisher_properties": { + "type": "array", + "description": "Properties from other publisher domains this agent is authorized for. Each entry specifies a publisher domain and which of their properties this agent can sell", + "items": { + "$ref": "core/publisher-property-selector.json" + }, + "minItems": 1 }, "collections": { + "type": "array", "description": "Optional collection constraints. When present, authorization only applies to inventory associated with these collections.", "items": { "$ref": "core/collection-selector.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "countries": { - "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", + "placement_ids": { + "type": "array", + "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", "items": { - "pattern": "^[A-Z]{2}$", "type": "string" }, - "minItems": 1, + "minItems": 1 + }, + "placement_tags": { "type": "array", + "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "items": { + "type": "string" + }, + "minItems": 1, "uniqueItems": true }, "delegation_type": { - "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint.", + "type": "string", "enum": [ "direct", "delegated", "ad_network" ], - "type": "string" - }, - "effective_from": { - "description": "Optional start time for this authorization window.", - "format": "date-time", - "type": "string" - }, - "effective_until": { - "description": "Optional end time for this authorization window.", - "format": "date-time", - "type": "string" + "description": "Commercial relationship for this inventory path. 'direct' means the publisher treats this as a direct way to buy from them, even if a third party operates the software. 'delegated' means the agent is authorized to sell on the publisher's behalf. 'ad_network' means the inventory is sold as part of a network/package context rather than as the publisher's direct endpoint." }, "exclusive": { - "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory.", - "type": "boolean" - }, - "placement_ids": { - "description": "Optional placement constraints. When present, authorization only applies to these placement IDs from the top-level placements array in this file.", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" + "type": "boolean", + "description": "Whether this agent is the publisher's sole authorized path for the scoped inventory slice. When false or absent, other authorized agents may also sell the same inventory." }, - "placement_tags": { - "description": "Optional placement tag constraints. When present, authorization only applies to placements whose tags include any of these publisher-defined values.", + "countries": { + "type": "array", + "description": "Optional ISO 3166-1 alpha-2 country codes limiting where this authorization applies. Omit for worldwide authorization.", "items": { - "type": "string" + "type": "string", + "pattern": "^[A-Z]{2}$" }, "minItems": 1, - "type": "array", "uniqueItems": true }, - "publisher_properties": { - "description": "Properties from other publisher domains this agent is authorized for. Each entry specifies a publisher domain and which of their properties this agent can sell", - "items": { - "$ref": "core/publisher-property-selector.json" - }, - "minItems": 1, - "type": "array" + "effective_from": { + "type": "string", + "format": "date-time", + "description": "Optional start time for this authorization window." + }, + "effective_until": { + "type": "string", + "format": "date-time", + "description": "Optional end time for this authorization window." }, "signing_keys": { + "type": "array", "description": "Optional publisher-attested public signing keys for this agent. Use these as the trust anchor for verifying signed agent responses instead of relying on key discovery from the agent domain alone.", "items": { "$ref": "core/agent-signing-key.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "url": { - "description": "The authorized agent's API endpoint URL", - "format": "uri", - "type": "string" + "encryption_keys": { + "type": "array", + "description": "X25519 public keys for TMPX exposure token encryption. Each key identifies a cluster master that can decrypt TMPX tokens. Used with HPKE mode_base \u2014 read replicas encrypt with this public key, only the master can decrypt.", + "items": { + "$ref": "core/agent-encryption-key.json" + }, + "minItems": 1 } }, "required": [ @@ -883,44 +591,52 @@ "authorization_type", "publisher_properties" ], - "type": "object" + "additionalProperties": true }, { - "additionalProperties": true, + "type": "object", "description": "Authorization for signals by specific signal IDs", "properties": { - "authorization_type": { - "const": "signal_ids", - "description": "Discriminator indicating authorization by specific signal IDs", - "type": "string" + "url": { + "type": "string", + "format": "uri", + "description": "The authorized signals agent's API endpoint URL" }, "authorized_for": { + "type": "string", "description": "Human-readable description of what signals this agent is authorized to resell", - "maxLength": 500, "minLength": 1, - "type": "string" + "maxLength": 500 + }, + "authorization_type": { + "type": "string", + "const": "signal_ids", + "description": "Discriminator indicating authorization by specific signal IDs" }, "signal_ids": { + "type": "array", "description": "Signal IDs this agent is authorized to resell. Resolved against the top-level signals array in this file", "items": { - "pattern": "^[a-zA-Z0-9_-]+$", - "type": "string" + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, "signing_keys": { + "type": "array", "description": "Optional publisher-attested public signing keys for this agent. Use these as the trust anchor for verifying signed agent responses instead of relying on key discovery from the agent domain alone.", "items": { "$ref": "core/agent-signing-key.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "url": { - "description": "The authorized signals agent's API endpoint URL", - "format": "uri", - "type": "string" + "encryption_keys": { + "type": "array", + "description": "X25519 public keys for TMPX exposure token encryption. Each key identifies a cluster master that can decrypt TMPX tokens. Used with HPKE mode_base \u2014 read replicas encrypt with this public key, only the master can decrypt.", + "items": { + "$ref": "core/agent-encryption-key.json" + }, + "minItems": 1 } }, "required": [ @@ -929,44 +645,52 @@ "authorization_type", "signal_ids" ], - "type": "object" + "additionalProperties": true }, { - "additionalProperties": true, + "type": "object", "description": "Authorization for signals by tag membership", "properties": { - "authorization_type": { - "const": "signal_tags", - "description": "Discriminator indicating authorization by signal tags", - "type": "string" + "url": { + "type": "string", + "format": "uri", + "description": "The authorized signals agent's API endpoint URL" }, "authorized_for": { + "type": "string", "description": "Human-readable description of what signals this agent is authorized to resell", - "maxLength": 500, "minLength": 1, - "type": "string" + "maxLength": 500 + }, + "authorization_type": { + "type": "string", + "const": "signal_tags", + "description": "Discriminator indicating authorization by signal tags" }, "signal_tags": { + "type": "array", "description": "Signal tags this agent is authorized for. Agent can resell all signals with these tags", "items": { - "pattern": "^[a-z0-9_-]+$", - "type": "string" + "type": "string", + "pattern": "^[a-z0-9_-]+$" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, "signing_keys": { + "type": "array", "description": "Optional publisher-attested public signing keys for this agent. Use these as the trust anchor for verifying signed agent responses instead of relying on key discovery from the agent domain alone.", "items": { "$ref": "core/agent-signing-key.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "url": { - "description": "The authorized signals agent's API endpoint URL", - "format": "uri", - "type": "string" + "encryption_keys": { + "type": "array", + "description": "X25519 public keys for TMPX exposure token encryption. Each key identifies a cluster master that can decrypt TMPX tokens. Used with HPKE mode_base \u2014 read replicas encrypt with this public key, only the master can decrypt.", + "items": { + "$ref": "core/agent-encryption-key.json" + }, + "minItems": 1 } }, "required": [ @@ -975,133 +699,43 @@ "authorization_type", "signal_tags" ], - "type": "object" + "additionalProperties": true } ] }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "collections": { - "description": "Collections produced or distributed by this publisher. Declares the content programs whose inventory is sold through authorized agents. Products in get_products responses reference these collections by collection_id.", - "items": { - "$ref": "core/collection.json" - }, - "type": "array" - }, - "contact": { - "additionalProperties": true, - "description": "Contact information for the entity managing this adagents.json file (may be publisher or third-party operator)", - "properties": { - "domain": { - "description": "Primary domain of the entity managing this file", - "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", - "type": "string" - }, - "email": { - "description": "Contact email for questions or issues with this authorization file", - "format": "email", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "name": { - "description": "Name of the entity managing this file (e.g., 'Meta Advertising Operations', 'Clear Channel Digital')", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "privacy_policy_url": { - "description": "URL to the entity's privacy policy. Used for consumer consent flows when interacting with this sales agent.", - "format": "uri", - "type": "string" - }, - "seller_id": { - "description": "Seller ID from IAB Tech Lab sellers.json (if applicable)", - "maxLength": 255, - "minLength": 1, - "type": "string" - }, - "tag_id": { - "description": "TAG Certified Against Fraud ID for verification (if applicable)", - "maxLength": 100, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "last_updated": { - "description": "ISO 8601 timestamp indicating when this file was last updated", - "format": "date-time", - "type": "string" - }, - "placement_tags": { - "additionalProperties": { - "additionalProperties": true, - "properties": { - "description": { - "description": "Description of what this placement tag represents", - "type": "string" - }, - "name": { - "description": "Human-readable name for this placement tag", - "type": "string" - } - }, - "required": [ - "name", - "description" - ], - "type": "object" - }, - "description": "Metadata for each tag referenced by placements. Provides human-readable context for publisher-defined placement tag values used in grouping and authorization.", - "type": "object" - }, - "placements": { - "description": "Canonical placement definitions for properties in this file. Products SHOULD reuse these placement_id values when exposing inventory in get_products, and authorized agents can scope authorization to these placement IDs.", - "items": { - "$ref": "core/placement-definition.json" - }, - "minItems": 1, - "type": "array" - }, - "properties": { - "description": "Array of all properties covered by this adagents.json file. Defines the canonical property list that authorized agents reference.", - "items": { - "$ref": "core/property.json" - }, - "minItems": 1, - "type": "array" + "last_updated": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 timestamp indicating when this file was last updated" }, "property_features": { + "type": "array", "description": "[AdCP 3.0] Optional list of agents that provide property feature data (certifications, scores, compliance status). Used for discovery - actual data is accessed through property list filters.", "items": { - "additionalProperties": true, + "type": "object", "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "The agent's API endpoint URL" + }, + "name": { + "type": "string", + "description": "Human-readable name of the vendor/agent (e.g., 'Scope3', 'TAG', 'OneTrust')" + }, "features": { + "type": "array", "description": "Feature IDs this agent provides (e.g., 'carbon_score', 'tag_certified_against_fraud'). Use get_adcp_capabilities on the agent for full definitions.", "items": { "type": "string" }, - "minItems": 1, - "type": "array" - }, - "name": { - "description": "Human-readable name of the vendor/agent (e.g., 'Scope3', 'TAG', 'OneTrust')", - "type": "string" + "minItems": 1 }, "publisher_id": { - "description": "Optional publisher identifier at this agent (for lookup)", - "type": "string" - }, - "url": { - "description": "The agent's API endpoint URL", - "format": "uri", - "type": "string" + "type": "string", + "description": "Optional publisher identifier at this agent (for lookup)" } }, "required": [ @@ -1109,68 +743,482 @@ "name", "features" ], - "type": "object" - }, - "type": "array" - }, - "signal_tags": { - "additionalProperties": { - "additionalProperties": true, - "properties": { - "description": { - "description": "Description of what this tag represents", - "type": "string" - }, - "name": { - "description": "Human-readable name for this tag", - "type": "string" - } - }, - "required": [ - "name", - "description" - ], - "type": "object" - }, - "description": "Metadata for each tag referenced by signals. Provides human-readable context for signal tag values.", - "type": "object" + "additionalProperties": true + } }, "signals": { + "type": "array", "description": "Signal catalog published by this data provider. Signals agents reference these signals via data_provider_domain + signal_id.", "items": { "$ref": "core/signal-definition.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 }, - "tags": { + "signal_tags": { + "type": "object", + "description": "Metadata for each tag referenced by signals. Provides human-readable context for signal tag values.", "additionalProperties": { - "additionalProperties": true, + "type": "object", "properties": { - "description": { - "description": "Description of what this tag represents", - "type": "string" - }, "name": { - "description": "Human-readable name for this tag", - "type": "string" + "type": "string", + "description": "Human-readable name for this tag" + }, + "description": { + "type": "string", + "description": "Description of what this tag represents" } }, "required": [ "name", "description" ], - "type": "object" - }, - "description": "Metadata for each tag referenced by properties. Provides human-readable context for property tag values.", - "type": "object" + "additionalProperties": true + } } }, "required": [ "authorized_agents" ], - "type": "object" + "additionalProperties": true } ], - "title": "AdCP Agents Authorization" + "examples": [ + { + "$schema": "/schemas/latest/adagents.json", + "authoritative_location": "https://cdn.example.com/adagents/v2/adagents.json", + "last_updated": "2025-01-15T10:00:00Z" + }, + { + "$schema": "/schemas/latest/adagents.json", + "properties": [ + { + "property_id": "example_site", + "property_type": "website", + "name": "Example Site", + "identifiers": [ + { + "type": "domain", + "value": "example.com" + } + ], + "publisher_domain": "example.com" + } + ], + "placements": [ + { + "placement_id": "homepage_banner", + "name": "Homepage Banner", + "tags": [ + "homepage", + "display", + "premium" + ], + "property_ids": [ + "example_site" + ], + "format_ids": [ + { + "agent_url": "https://creative.example.com", + "id": "display_728x90" + } + ] + } + ], + "placement_tags": { + "homepage": { + "name": "Homepage", + "description": "Placements that render on the homepage" + }, + "display": { + "name": "Display", + "description": "Standard display placements" + }, + "premium": { + "name": "Premium", + "description": "Premium monetization placements" + } + }, + "authorized_agents": [ + { + "url": "https://agent.example.com", + "authorized_for": "Official sales agent", + "authorization_type": "property_tags", + "property_tags": [ + "all" + ], + "placement_ids": [ + "homepage_banner" + ], + "delegation_type": "direct", + "exclusive": true, + "countries": [ + "US", + "CA" + ], + "effective_from": "2025-01-01T00:00:00Z" + } + ], + "tags": { + "all": { + "name": "All Properties", + "description": "All properties in this file" + } + }, + "last_updated": "2025-01-10T12:00:00Z" + }, + { + "$schema": "/schemas/latest/adagents.json", + "contact": { + "name": "Meta Advertising Operations", + "email": "adops@meta.com", + "domain": "meta.com", + "seller_id": "pub-meta-12345", + "tag_id": "12345", + "privacy_policy_url": "https://www.meta.com/privacy/policy" + }, + "properties": [ + { + "property_type": "mobile_app", + "name": "Instagram", + "identifiers": [ + { + "type": "ios_bundle", + "value": "com.burbn.instagram" + }, + { + "type": "android_package", + "value": "com.instagram.android" + } + ], + "tags": [ + "meta_network", + "social_media" + ], + "supported_channels": [ + "social", + "display", + "olv" + ], + "publisher_domain": "instagram.com" + }, + { + "property_type": "mobile_app", + "name": "Facebook", + "identifiers": [ + { + "type": "ios_bundle", + "value": "com.facebook.Facebook" + }, + { + "type": "android_package", + "value": "com.facebook.katana" + } + ], + "tags": [ + "meta_network", + "social_media" + ], + "supported_channels": [ + "social", + "display", + "olv" + ], + "publisher_domain": "facebook.com" + }, + { + "property_type": "mobile_app", + "name": "WhatsApp", + "identifiers": [ + { + "type": "ios_bundle", + "value": "net.whatsapp.WhatsApp" + }, + { + "type": "android_package", + "value": "com.whatsapp" + } + ], + "tags": [ + "meta_network", + "messaging" + ], + "supported_channels": [ + "social", + "display" + ], + "publisher_domain": "whatsapp.com" + } + ], + "tags": { + "meta_network": { + "name": "Meta Network", + "description": "All Meta-owned properties" + }, + "social_media": { + "name": "Social Media Apps", + "description": "Social networking applications" + }, + "messaging": { + "name": "Messaging Apps", + "description": "Messaging and communication apps" + } + }, + "authorized_agents": [ + { + "url": "https://meta-ads.com", + "authorized_for": "All Meta properties", + "authorization_type": "property_tags", + "property_tags": [ + "meta_network" + ] + } + ], + "last_updated": "2025-01-10T15:30:00Z" + }, + { + "$schema": "/schemas/latest/adagents.json", + "contact": { + "name": "Tumblr Advertising" + }, + "properties": [ + { + "property_type": "website", + "name": "Tumblr Corporate", + "identifiers": [ + { + "type": "domain", + "value": "tumblr.com" + } + ], + "tags": [ + "corporate" + ], + "publisher_domain": "tumblr.com" + } + ], + "tags": { + "corporate": { + "name": "Corporate Properties", + "description": "Tumblr-owned corporate properties (not user blogs)" + } + }, + "authorized_agents": [ + { + "url": "https://tumblr-sales.com", + "authorized_for": "Tumblr corporate properties only", + "authorization_type": "property_tags", + "property_tags": [ + "corporate" + ] + } + ], + "last_updated": "2025-01-10T16:00:00Z" + }, + { + "$schema": "/schemas/latest/adagents.json", + "contact": { + "name": "Example Third-Party Sales Agent", + "email": "sales@agent.example", + "domain": "agent.example" + }, + "authorized_agents": [ + { + "url": "https://agent.example/api", + "authorized_for": "CNN CTV properties via publisher authorization", + "authorization_type": "publisher_properties", + "publisher_properties": [ + { + "publisher_domain": "cnn.com", + "selection_type": "by_id", + "property_ids": [ + "cnn_ctv_app" + ] + } + ] + }, + { + "url": "https://agent.example/api", + "authorized_for": "All CTV properties from multiple publishers", + "authorization_type": "publisher_properties", + "publisher_properties": [ + { + "publisher_domain": "cnn.com", + "selection_type": "by_tag", + "property_tags": [ + "ctv" + ] + }, + { + "publisher_domain": "espn.com", + "selection_type": "by_tag", + "property_tags": [ + "ctv" + ] + } + ] + } + ], + "last_updated": "2025-01-10T17:00:00Z" + }, + { + "$schema": "/schemas/latest/adagents.json", + "contact": { + "name": "Premium News Publisher", + "email": "adops@news.example.com", + "domain": "news.example.com" + }, + "properties": [ + { + "property_type": "website", + "name": "News Example", + "identifiers": [ + { + "type": "domain", + "value": "news.example.com" + } + ], + "tags": [ + "premium", + "news" + ], + "publisher_domain": "news.example.com" + } + ], + "tags": { + "premium": { + "name": "Premium Properties", + "description": "High-quality, brand-safe properties" + }, + "news": { + "name": "News Properties", + "description": "News and journalism content" + } + }, + "authorized_agents": [ + { + "url": "https://sales.news.example.com", + "authorized_for": "All news properties", + "authorization_type": "property_tags", + "property_tags": [ + "news" + ] + } + ], + "property_features": [ + { + "url": "https://api.scope3.com", + "name": "Scope3", + "features": [ + "carbon_score", + "sustainability_grade" + ], + "publisher_id": "pub_news_12345" + }, + { + "url": "https://api.tagtoday.net", + "name": "TAG", + "features": [ + "tag_certified_against_fraud", + "tag_brand_safety_certified" + ] + }, + { + "url": "https://api.onetrust.com", + "name": "OneTrust", + "features": [ + "gdpr_compliant", + "tcf_registered", + "ccpa_compliant" + ], + "publisher_id": "ot_news_67890" + } + ], + "last_updated": "2025-01-10T18:00:00Z" + }, + { + "$schema": "/schemas/latest/adagents.json", + "contact": { + "name": "Polk Automotive Data", + "email": "partnerships@polk.com", + "domain": "polk.com" + }, + "signals": [ + { + "id": "likely_tesla_buyers", + "name": "Likely Tesla Buyers", + "description": "Consumers modeled as likely to purchase a Tesla in the next 12 months based on vehicle registration, financial, and behavioral data", + "value_type": "binary", + "category": "purchase_intent", + "tags": [ + "automotive", + "premium" + ] + }, + { + "id": "vehicle_ownership", + "name": "Current Vehicle Ownership", + "description": "Current vehicle make owned by the consumer", + "value_type": "categorical", + "category": "ownership", + "allowed_values": [ + "tesla", + "bmw", + "mercedes", + "audi", + "lexus", + "other_luxury", + "non_luxury" + ], + "tags": [ + "automotive" + ] + }, + { + "id": "purchase_propensity", + "name": "Auto Purchase Propensity", + "description": "Likelihood score of purchasing any new vehicle in the next 6 months", + "value_type": "numeric", + "category": "purchase_intent", + "range": { + "min": 0, + "max": 1, + "unit": "score" + }, + "tags": [ + "automotive" + ] + } + ], + "signal_tags": { + "automotive": { + "name": "Automotive Signals", + "description": "Vehicle-related audience segments" + }, + "premium": { + "name": "Premium Signals", + "description": "High-value premium audience segments" + } + }, + "authorized_agents": [ + { + "url": "https://liveramp.com/.well-known/adcp/signals", + "authorized_for": "All Polk automotive signals via LiveRamp", + "authorization_type": "signal_tags", + "signal_tags": [ + "automotive" + ] + }, + { + "url": "https://the-trade-desk.com/.well-known/adcp/signals", + "authorized_for": "Polk premium signals only", + "authorization_type": "signal_ids", + "signal_ids": [ + "likely_tesla_buyers" + ] + } + ], + "last_updated": "2025-01-15T10:00:00Z" + } + ] } \ No newline at end of file diff --git a/schemas/cache/brand.json b/schemas/cache/brand.json index 33214daac..48ab4bbc9 100644 --- a/schemas/cache/brand.json +++ b/schemas/cache/brand.json @@ -1,783 +1,1101 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Brand Discovery", + "description": "Brand identity and discovery file. Hosted at /.well-known/brand.json on house domains. Contains the full brand portfolio with identity, creative assets, and digital properties. Brands are identified by house + brand_id (like properties are identified by publisher + property_id). Supports variants: house portfolio (full brand data), brand agent (agent provides brand info via MCP), house redirect (pointer to house domain), or authoritative location redirect.", "definitions": { - "asset": { - "additionalProperties": true, - "description": "Brand asset (image, video, audio, text)", + "domain": { + "type": "string", + "description": "A valid domain name", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$" + }, + "brand_id": { + "type": "string", + "description": "Brand identifier within the house portfolio. Lowercase alphanumeric with underscores. House chooses this ID.", + "pattern": "^[a-z0-9_]+$" + }, + "localized_name": { + "type": "object", + "description": "A localized name with BCP 47 locale code key (e.g., 'en_US', 'fr_CA', 'zh_CN') and name value. Bare language codes ('en') are accepted as wildcards for backwards compatibility.", + "minProperties": 1, + "maxProperties": 1, + "additionalProperties": { + "type": "string", + "minLength": 1 + } + }, + "keller_type": { + "type": "string", + "enum": [ + "master", + "sub_brand", + "endorsed", + "independent" + ], + "description": "Brand architecture type from Keller's theory. master: primary brand of house. sub_brand: carries parent name (Nike SB). endorsed: independent identity backed by parent (Air Jordan 'by Nike'). independent: operates separately (Converse under Nike, Inc.)" + }, + "logo": { + "type": "object", + "description": "Brand logo asset with structured fields for orientation, background compatibility, and variant type", "properties": { - "asset_id": { - "description": "Unique identifier", - "type": "string" - }, - "asset_type": { - "$ref": "enums/asset-content-type.json", - "description": "Type of asset content" + "url": { + "type": "string", + "format": "uri", + "description": "URL to the logo asset" }, - "description": { - "description": "Asset description or usage notes", - "type": "string" + "orientation": { + "type": "string", + "enum": [ + "square", + "horizontal", + "vertical", + "stacked" + ], + "description": "Logo aspect ratio orientation. square: ~1:1, horizontal: wide, vertical: tall, stacked: vertically arranged elements" }, - "duration_seconds": { - "description": "Video/audio duration in seconds", - "type": "number" + "background": { + "type": "string", + "enum": [ + "dark-bg", + "light-bg", + "transparent-bg" + ], + "description": "Background compatibility. dark-bg: use on dark backgrounds, light-bg: use on light backgrounds, transparent-bg: has transparent background" }, - "file_size_bytes": { - "description": "File size in bytes", - "type": "integer" + "variant": { + "type": "string", + "enum": [ + "primary", + "secondary", + "icon", + "wordmark", + "full-lockup" + ], + "description": "Logo variant type. primary: main logo, secondary: alternative, icon: symbol only, wordmark: text only, full-lockup: complete logo" }, - "format": { - "description": "File format (e.g., 'jpg', 'mp4', 'mp3')", - "type": "string" + "tags": { + "type": "array", + "description": "Additional semantic tags for custom categorization beyond the standard orientation, background, and variant fields", + "items": { + "type": "string" + } }, - "height": { - "description": "Image/video height in pixels", - "type": "integer" + "usage": { + "type": "string", + "description": "Human-readable description of when to use this logo variant (e.g., 'Primary logo for use on light backgrounds')" }, - "metadata": { - "additionalProperties": true, - "description": "Additional asset-specific metadata", - "type": "object" + "width": { + "type": "integer", + "description": "Width in pixels" }, - "name": { - "description": "Human-readable name", - "type": "string" + "height": { + "type": "integer", + "description": "Height in pixels" + } + }, + "required": [ + "url" + ], + "additionalProperties": true + }, + "hex_color": { + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$", + "description": "A single hex color value" + }, + "color_value": { + "oneOf": [ + { + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, - "tags": { - "description": "Tags for discovery (e.g., 'hero', 'lifestyle', 'product', 'holiday')", + { + "type": "array", "items": { - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, - "type": "array" + "minItems": 1 + } + ] + }, + "colors": { + "type": "object", + "description": "Brand color palette. Each role accepts a single hex color or an array of hex colors for brands with multiple values per role. Beyond the core five roles, brands can provide additional color roles for finer granularity \u2014 heading, body, label, border, divider, surface_1, surface_2, etc.", + "properties": { + "primary": { + "$ref": "#/definitions/color_value" + }, + "secondary": { + "$ref": "#/definitions/color_value" + }, + "accent": { + "$ref": "#/definitions/color_value" + }, + "background": { + "$ref": "#/definitions/color_value" + }, + "text": { + "$ref": "#/definitions/color_value" + }, + "heading": { + "$ref": "#/definitions/color_value" + }, + "body": { + "$ref": "#/definitions/color_value" + }, + "label": { + "$ref": "#/definitions/color_value" + }, + "border": { + "$ref": "#/definitions/color_value" + }, + "divider": { + "$ref": "#/definitions/color_value" + }, + "surface_1": { + "$ref": "#/definitions/color_value" }, + "surface_2": { + "$ref": "#/definitions/color_value" + } + }, + "additionalProperties": { + "$ref": "#/definitions/color_value" + } + }, + "font_file": { + "type": "object", + "description": "A font file with weight, style, and variable font metadata", + "properties": { "url": { - "description": "URL to CDN-hosted asset file", + "type": "string", "format": "uri", - "type": "string" + "pattern": "^https://", + "description": "HTTPS URL to the font file (WOFF2, TTF, or OTF)" }, - "width": { - "description": "Image/video width in pixels", - "type": "integer" + "weight": { + "type": "integer", + "minimum": 100, + "maximum": 900, + "description": "CSS numeric font-weight for static fonts (100-900)" + }, + "weight_range": { + "type": "array", + "items": { + "type": "integer", + "minimum": 100, + "maximum": 900 + }, + "minItems": 2, + "maxItems": 2, + "description": "Variable font weight axis range as [min, max] (e.g., [100, 900]). Use instead of weight for variable fonts." + }, + "style": { + "type": "string", + "enum": [ + "normal", + "italic", + "oblique" + ], + "description": "CSS font-style" } }, "required": [ - "asset_id", - "asset_type", "url" ], - "type": "object" + "additionalProperties": true }, - "asset_library": { - "additionalProperties": true, - "description": "A managed asset library (icon set, illustration system, image collection). The URL is for human access; agent-facing DAM integration is under investigation.", - "properties": { - "color_guide": { - "additionalProperties": true, - "description": "Color guide for the asset library defining roles and palettes", + "font_role": { + "description": "A font role entry. Either a CSS font-family string (simple) or a structured object with family name and font files (rich).", + "oneOf": [ + { + "type": "string", + "description": "CSS font-family name (e.g., 'Montserrat', 'Arial, sans-serif')" + }, + { + "type": "object", + "description": "Structured font with family name, downloadable font files, and typographic metadata", "properties": { - "palettes": { - "description": "Named color palettes mapping roles to specific colors", + "family": { + "type": "string", + "description": "CSS font-family name (e.g., 'Brand Sans')" + }, + "files": { + "type": "array", "items": { - "additionalProperties": true, - "properties": { - "colors": { - "additionalProperties": { - "$ref": "#/definitions/hex_color" - }, - "description": "Map of role names to hex color values", - "type": "object" - }, - "name": { - "description": "Palette name", - "type": "string" - } - }, - "required": [ - "name", - "colors" - ], - "type": "object" + "$ref": "#/definitions/font_file" }, - "type": "array" + "maxItems": 36, + "description": "Font files for different weights and styles" }, - "roles": { - "description": "Named color roles used in the library (e.g., base, shadow_1, highlight_1, stroke)", + "opentype_features": { + "type": "array", "items": { - "type": "string" + "type": "string", + "pattern": "^[a-z0-9]{4}$" + }, + "maxItems": 20, + "description": "OpenType feature tags to enable (e.g., ['ss01', 'tnum', 'cv01']). These are four-character tags per the OpenType spec." + }, + "fallbacks": { + "type": "array", + "items": { + "type": "string", + "maxLength": 100 }, - "type": "array" + "maxItems": 10, + "description": "Ordered fallback font-family names for when the primary font is unavailable or does not support the required script (e.g., ['Noto Sans Arabic', 'Noto Sans SC', 'sans-serif'])" } }, - "type": "object" - }, - "description": { - "description": "Description of the library contents and usage", - "type": "string" - }, - "name": { - "description": "Display name of the asset library", - "type": "string" - }, - "type": { - "description": "Type of asset library", - "enum": [ - "icon_set", - "illustration_system", - "image_library", - "video_library", - "template_library" + "required": [ + "family" ], - "type": "string" + "additionalProperties": true + } + ] + }, + "fonts": { + "type": "object", + "description": "Brand typography. Each key is a role name (e.g., 'primary', 'secondary') referenced by type_scale entries. Values are either a CSS font-family string or a structured object with font files for reliable resolution.", + "maxProperties": 20, + "properties": { + "primary": { + "$ref": "#/definitions/font_role", + "description": "Primary font family" }, - "url": { - "description": "URL to the asset library (for human access)", - "format": "uri", - "type": "string" + "secondary": { + "$ref": "#/definitions/font_role", + "description": "Secondary font family" } }, - "required": [ - "name", - "url" - ], - "type": "object" + "additionalProperties": { + "$ref": "#/definitions/font_role" + } }, - "authorized_operator": { - "additionalProperties": true, - "description": "An entity authorized to represent brands from this house. Verified by resolving the operator's domain.", + "asset": { + "type": "object", + "description": "Brand asset (image, video, audio, text)", "properties": { - "brands": { - "description": "Brand IDs this operator is authorized for. Use ['*'] for all brands in the portfolio.", - "items": { - "pattern": "^([a-z0-9_]+|\\*)$", - "type": "string" - }, - "minItems": 1, - "type": "array" + "asset_id": { + "type": "string", + "description": "Unique identifier" }, - "countries": { - "description": "ISO 3166-1 alpha-2 country codes where this authorization applies. Omit for global authorization.", + "asset_type": { + "$ref": "enums/asset-content-type.json", + "description": "Type of asset content" + }, + "url": { + "type": "string", + "format": "uri", + "description": "URL to CDN-hosted asset file" + }, + "tags": { + "type": "array", "items": { - "pattern": "^[A-Z]{2}$", "type": "string" }, - "type": "array" + "description": "Tags for discovery (e.g., 'hero', 'lifestyle', 'product', 'holiday')" }, - "domain": { - "$ref": "#/definitions/domain", - "description": "Domain of the authorized operator (e.g., 'groupm.com')" + "name": { + "type": "string", + "description": "Human-readable name" + }, + "description": { + "type": "string", + "description": "Asset description or usage notes" + }, + "width": { + "type": "integer", + "description": "Image/video width in pixels" + }, + "height": { + "type": "integer", + "description": "Image/video height in pixels" + }, + "duration_seconds": { + "type": "number", + "description": "Video/audio duration in seconds" + }, + "file_size_bytes": { + "type": "integer", + "description": "File size in bytes" + }, + "format": { + "type": "string", + "description": "File format (e.g., 'jpg', 'mp4', 'mp3')" + }, + "metadata": { + "type": "object", + "description": "Additional asset-specific metadata", + "additionalProperties": true } }, "required": [ - "domain", - "brands" + "asset_id", + "asset_type", + "url" ], - "type": "object" + "additionalProperties": true }, - "brand": { - "additionalProperties": true, - "description": "A brand within a house portfolio. Combines identity (who) with creative assets (how to represent). Referenced as domain + brand_id.", + "property": { + "type": "object", + "description": "A digital property associated with a brand. Defaults to owned; use 'relationship' to declare direct, delegated, or ad_network properties. These values match the delegation_type field in adagents.json, creating a bilateral verification chain: the operator declares the relationship here, the publisher confirms by setting the same delegation_type on the agent's authorization in their adagents.json.", "properties": { - "assets": { - "description": "Brand asset library", - "items": { - "$ref": "#/definitions/asset" - }, - "type": "array" - }, - "avatar": { - "additionalProperties": true, - "description": "Visual avatar configuration", - "properties": { - "avatar_id": { - "type": "string" - }, - "provider": { - "type": "string" - }, - "settings": { - "additionalProperties": true, - "type": "object" - } - }, - "type": "object" + "type": { + "type": "string", + "enum": [ + "website", + "mobile_app", + "ctv_app", + "desktop_app", + "dooh", + "podcast", + "radio", + "streaming_audio" + ], + "description": "Property type" }, - "brand_agent": { - "$ref": "#/definitions/brand_agent", - "description": "Brand agent that provides dynamic brand data via MCP" + "identifier": { + "type": "string", + "description": "Property identifier - domain for websites, bundle ID for apps", + "minLength": 1 }, - "collections": { - "description": "Collections this person or brand is associated with. Enables bidirectional linking: a collection's talent references brand.json via brand_url, and brand.json links back to collections.", + "store": { + "type": "string", + "enum": [ + "apple", + "google", + "amazon", + "roku", + "samsung", + "lg", + "other" + ], + "description": "App store for mobile/CTV apps" + }, + "region": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code or 'global'", + "pattern": "^([A-Z]{2}|global)$" + }, + "primary": { + "type": "boolean", + "default": false, + "description": "Whether this is the primary property for the brand" + }, + "relationship": { + "type": "string", + "enum": [ + "owned", + "direct", + "delegated", + "ad_network" + ], + "default": "owned", + "description": "How this brand relates to the property, using the same vocabulary as adagents.json delegation_type. 'owned': the brand owns and operates this property (default). 'direct': the brand is the direct sales path for this property, even if a third party operates the software (e.g., a publisher's in-house ad team using a vendor's tech). 'delegated': the brand manages monetization for this property \u2014 they are in charge of ad sales (e.g., Mediavine managing a food blog). 'ad_network': the brand sells this property's inventory as part of a network or exchange \u2014 they are a path to the inventory, not the path (e.g., PubMatic as an SSP). For non-owned properties, the publisher confirms the relationship by setting the matching delegation_type on the agent's authorization in their adagents.json." + } + }, + "required": [ + "type", + "identifier" + ], + "additionalProperties": true + }, + "product_catalog": { + "type": "object", + "description": "Product catalog for e-commerce brands", + "properties": { + "feed_url": { + "type": "string", + "format": "uri", + "description": "URL to product catalog feed" + }, + "feed_format": { + "type": "string", + "enum": [ + "google_merchant_center", + "facebook_catalog", + "openai_product_feed", + "custom" + ], + "description": "Format of the product feed" + }, + "categories": { + "type": "array", "items": { - "additionalProperties": true, - "properties": { - "collection_id": { - "description": "Collection identifier as used in the seller's get_products responses", - "type": "string" - }, - "name": { - "description": "Human-readable collection name", - "type": "string" - }, - "role": { - "$ref": "enums/talent-role.json", - "description": "This person's role on the collection" - }, - "seller_agent_url": { - "description": "URL of the sales agent that sells inventory for this collection. Buyer agents can query this agent for collection products.", - "format": "uri", - "type": "string" - } - }, - "required": [ - "name" - ], - "type": "object" + "type": "string" }, - "type": "array" + "description": "Product categories available in the catalog" }, - "colors": { - "$ref": "#/definitions/colors" + "last_updated": { + "type": "string", + "format": "date-time", + "description": "When the product catalog was last updated" }, - "contact": { - "description": "Brand-level contact information", + "update_frequency": { + "type": "string", + "enum": [ + "realtime", + "hourly", + "daily", + "weekly" + ], + "description": "How frequently the product catalog is updated" + }, + "agentic_checkout": { + "type": "object", + "description": "Agentic checkout endpoint configuration", "properties": { - "email": { - "description": "Contact email", - "format": "email", - "type": "string" + "endpoint": { + "type": "string", + "format": "uri", + "description": "Base URL for checkout session API" }, - "phone": { - "description": "Contact phone number", - "type": "string" - } - }, - "type": "object" - }, - "description": { - "description": "Brand description", - "type": "string" - }, - "disclaimers": { - "description": "Legal disclaimers for creatives", - "items": { - "properties": { - "context": { - "type": "string" - }, - "required": { - "default": true, - "type": "boolean" - }, - "text": { + "spec": { + "type": "string", + "enum": [ + "openai_agentic_checkout_v1" + ], + "description": "Checkout API specification" + }, + "supported_payment_providers": { + "type": "array", + "description": "Payment providers supported by this checkout endpoint", + "items": { "type": "string" } - }, - "required": [ - "text" - ], - "type": "object" + } }, - "type": "array" - }, - "fonts": { - "$ref": "#/definitions/fonts" - }, + "required": [ + "endpoint", + "spec" + ] + } + }, + "required": [ + "feed_url" + ], + "additionalProperties": true + }, + "brand": { + "type": "object", + "description": "A brand within a house portfolio. Combines identity (who) with creative assets (how to represent). Referenced as domain + brand_id.", + "properties": { "id": { "$ref": "#/definitions/brand_id", "description": "Brand identifier within the house. House chooses this ID." }, - "industries": { - "description": "Brand industries (e.g., ['automotive'] or ['healthcare.pharmaceutical', 'cpg'] for a consumer health company). Describes what the company does \u2014 not what regulatory regimes apply (use policy_categories for that). When create_media_buy omits advertiser_industry, sellers may infer from this field.", - "items": { - "$ref": "enums/advertiser-industry.json" - }, - "minItems": 1, - "type": "array" - }, - "keller_type": { - "$ref": "#/definitions/keller_type" - }, - "logos": { - "description": "Brand logo assets", - "items": { - "$ref": "#/definitions/logo" - }, - "type": "array" + "url": { + "type": "string", + "format": "uri", + "description": "Primary brand URL for context and asset discovery" }, "names": { + "type": "array", "description": "Localized brand names. Multiple entries per language allowed for aliases.", "items": { "$ref": "#/definitions/localized_name" }, - "minItems": 1, - "type": "array" + "minItems": 1 + }, + "keller_type": { + "$ref": "#/definitions/keller_type" }, "parent_brand": { "$ref": "#/definitions/brand_id", "description": "Parent brand ID for sub-brands and endorsed brands" }, - "privacy_policy_url": { - "description": "URL to the brand's privacy policy", - "format": "uri", - "type": "string" - }, - "product_catalog": { - "$ref": "#/definitions/product_catalog" + "description": { + "type": "string", + "description": "Brand description" }, - "properties": { - "description": "Digital properties owned by this brand", + "industries": { + "type": "array", "items": { - "$ref": "#/definitions/property" + "type": "string" }, - "type": "array" + "minItems": 1, + "description": "Brand industries (e.g., ['automotive'] or ['pharmaceutical', 'cpg'] for a consumer health company). Describes what the company does \u2014 not what regulatory regimes apply (use policy_categories for that)." }, - "rights_agent": { - "$ref": "#/definitions/rights_agent", - "description": "Rights licensing agent for this brand" + "target_audience": { + "type": "string", + "description": "Primary target audience" }, - "tagline": { - "description": "Brand tagline or slogan. Accepts a plain string or a localized array matching the names pattern.", - "oneOf": [ - { - "description": "Plain tagline string for backwards compatibility", - "type": "string" - }, - { - "description": "Localized taglines with BCP 47 locale codes", - "items": { - "$ref": "#/definitions/localized_name" - }, - "minItems": 1, - "type": "array" - } - ] + "logos": { + "type": "array", + "items": { + "$ref": "#/definitions/logo" + }, + "description": "Brand logo assets" }, - "target_audience": { - "description": "Primary target audience", - "type": "string" + "colors": { + "$ref": "#/definitions/colors" + }, + "fonts": { + "$ref": "#/definitions/fonts" }, "tone": { "description": "Brand voice and messaging tone guidelines", "oneOf": [ { - "description": "Simple tone descriptors for backwards compatibility", - "type": "string" + "type": "string", + "description": "Simple tone descriptors for backwards compatibility" }, { + "type": "object", "description": "Structured brand voice guidelines", "properties": { + "voice": { + "type": "string", + "description": "High-level voice descriptor (e.g., 'warm and inviting', 'professional and trustworthy')" + }, "attributes": { + "type": "array", "description": "Personality traits that characterize the brand voice", "items": { "type": "string" - }, - "type": "array" - }, - "donts": { - "description": "Guardrails to avoid brand violations - what NOT to do", - "items": { - "type": "string" - }, - "type": "array" + } }, "dos": { + "type": "array", "description": "Guidance for copy generation - what TO do", "items": { "type": "string" - }, - "type": "array" + } }, - "voice": { - "description": "High-level voice descriptor (e.g., 'warm and inviting', 'professional and trustworthy')", - "type": "string" + "donts": { + "type": "array", + "description": "Guardrails to avoid brand violations - what NOT to do", + "items": { + "type": "string" + } } - }, - "type": "object" + } } ] }, - "url": { - "description": "Primary brand URL for context and asset discovery", - "format": "uri", - "type": "string" + "tagline": { + "oneOf": [ + { + "type": "string", + "description": "Plain tagline string for backwards compatibility" + }, + { + "type": "array", + "description": "Localized taglines with BCP 47 locale codes", + "items": { + "$ref": "#/definitions/localized_name" + }, + "minItems": 1 + } + ], + "description": "Brand tagline or slogan. Accepts a plain string or a localized array matching the names pattern." }, - "visual_guidelines": { - "$ref": "#/definitions/visual_guidelines", - "description": "Structured visual rules for generative creative systems" + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/asset" + }, + "description": "Brand asset library" }, - "voice_synthesis": { - "additionalProperties": true, - "description": "TTS voice synthesis configuration for AI-generated audio", - "properties": { + "properties": { + "type": "array", + "items": { + "$ref": "#/definitions/property" + }, + "description": "Digital properties associated with this brand \u2014 owned, managed, or represented" + }, + "product_catalog": { + "$ref": "#/definitions/product_catalog" + }, + "privacy_policy_url": { + "type": "string", + "format": "uri", + "description": "URL to the brand's privacy policy" + }, + "disclaimers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "context": { + "type": "string" + }, + "required": { + "type": "boolean", + "default": true + } + }, + "required": [ + "text" + ] + }, + "description": "Legal disclaimers for creatives" + }, + "voice_synthesis": { + "type": "object", + "description": "TTS voice synthesis configuration for AI-generated audio", + "properties": { "provider": { "type": "string" }, + "voice_id": { + "type": "string" + }, "settings": { - "additionalProperties": true, - "type": "object" + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "avatar": { + "type": "object", + "description": "Visual avatar configuration", + "properties": { + "provider": { + "type": "string" }, - "voice_id": { + "avatar_id": { "type": "string" + }, + "settings": { + "type": "object", + "additionalProperties": true } }, - "type": "object" + "additionalProperties": true + }, + "visual_guidelines": { + "$ref": "#/definitions/visual_guidelines", + "description": "Structured visual rules for generative creative systems" + }, + "agents": { + "$ref": "#/definitions/agents", + "description": "Agents authorized to act on behalf of this brand. Overrides house-level agents of the same type." + }, + "brand_agent": { + "$ref": "#/definitions/brand_agent", + "description": "Deprecated: use agents array with type 'brand' instead. Brand agent that provides dynamic brand data via MCP.", + "deprecated": true + }, + "rights_agent": { + "$ref": "#/definitions/rights_agent", + "description": "Deprecated: use agents array with type 'rights' instead. Rights licensing agent for this brand.", + "deprecated": true + }, + "contact": { + "type": "object", + "description": "Brand-level contact information", + "properties": { + "email": { + "type": "string", + "format": "email", + "description": "Contact email" + }, + "phone": { + "type": "string", + "description": "Contact phone number" + } + } + }, + "collections": { + "type": "array", + "description": "Collections this person or brand is associated with. Enables bidirectional linking: a collection's talent references brand.json via brand_url, and brand.json links back to collections.", + "items": { + "type": "object", + "properties": { + "collection_id": { + "type": "string", + "description": "Collection identifier as used in the seller's get_products responses" + }, + "name": { + "type": "string", + "description": "Human-readable collection name" + }, + "role": { + "$ref": "enums/talent-role.json", + "description": "This person's role on the collection" + }, + "seller_agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the sales agent that sells inventory for this collection. Buyer agents can query this agent for collection products." + } + }, + "required": [ + "name" + ], + "additionalProperties": true + } } }, "required": [ "id", "names" ], - "type": "object" + "additionalProperties": true + }, + "house": { + "type": "object", + "description": "Corporate or organizational entity that owns brands", + "properties": { + "domain": { + "$ref": "#/definitions/domain", + "description": "The house's domain where brand.json is hosted" + }, + "name": { + "type": "string", + "description": "Primary display name of the house", + "minLength": 1 + }, + "names": { + "type": "array", + "description": "Localized house names including legal name, stock symbol, etc.", + "items": { + "$ref": "#/definitions/localized_name" + } + }, + "architecture": { + "type": "string", + "enum": [ + "branded_house", + "house_of_brands", + "hybrid" + ], + "description": "Brand architecture model: branded_house (Google), house_of_brands (P&G), hybrid (Nike)" + }, + "agents": { + "$ref": "#/definitions/agents", + "description": "House-level agents that apply to all brands unless overridden at the brand level" + } + }, + "required": [ + "domain", + "name" + ], + "additionalProperties": true }, "brand_agent": { - "additionalProperties": true, + "type": "object", "description": "Reference to a brand agent that provides brand data via MCP", "properties": { - "id": { - "description": "Agent identifier (useful for logging, multi-tenant DAMs)", - "pattern": "^[a-z0-9_]+$", - "type": "string" - }, "url": { - "description": "Brand agent MCP endpoint URL", + "type": "string", "format": "uri", "pattern": "^https://", - "type": "string" + "description": "Brand agent MCP endpoint URL" + }, + "id": { + "type": "string", + "description": "Agent identifier (useful for logging, multi-tenant DAMs)", + "pattern": "^[a-z0-9_]+$" } }, "required": [ "url", "id" ], - "type": "object" - }, - "brand_id": { - "description": "Brand identifier within the house portfolio. Lowercase alphanumeric with underscores. House chooses this ID.", - "pattern": "^[a-z0-9_]+$", - "type": "string" + "additionalProperties": true }, - "brand_shapes": { - "additionalProperties": true, - "description": "Distinctive shapes used as part of brand visual identity", + "rights_agent": { + "type": "object", + "description": "Rights licensing agent for this brand. Provides discovery, pricing, and acquisition of licensable rights via MCP. Use get_rights and acquire_rights tasks to interact.", "properties": { - "primary_shape": { - "description": "Primary brand shape (e.g., 'rounded_rectangle', 'circle', 'hexagon')", - "type": "string" + "url": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "Rights agent MCP endpoint URL" }, - "secondary_shapes": { - "description": "Secondary shapes in the brand vocabulary", + "id": { + "type": "string", + "description": "Agent identifier", + "pattern": "^[a-z0-9_]+$" + }, + "available_uses": { + "type": "array", + "description": "Rights uses available for licensing through this agent", "items": { - "type": "string" + "$ref": "enums/right-use.json" }, - "type": "array" + "minItems": 1 }, - "usage": { - "additionalProperties": true, - "description": "Shape usage rules", - "properties": { - "max_per_layout": { - "description": "Maximum distinct shapes per layout", - "type": "integer" - }, - "overlap_allowed": { - "description": "Whether shapes may overlap", - "type": "boolean" - } + "right_types": { + "type": "array", + "description": "Types of rights available", + "items": { + "$ref": "enums/right-type.json" }, - "type": "object" - } - }, - "type": "object" - }, - "color_value": { - "oneOf": [ - { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "minItems": 1 }, - { + "countries": { + "type": "array", + "description": "Countries where rights are available (ISO 3166-1 alpha-2)", "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - "minItems": 1, - "type": "array" + "type": "string", + "pattern": "^[A-Z]{2}$" + } } - ] + }, + "required": [ + "url", + "id", + "available_uses" + ], + "additionalProperties": true }, - "colors": { - "additionalProperties": true, - "description": "Brand color palette. Each role accepts a single hex color or an array of hex colors for brands with multiple values per role.", + "brand_agent_entry": { + "type": "object", + "description": "An agent declared by a brand or house. Each entry identifies one agent endpoint and its functional role in the advertising ecosystem.", "properties": { - "accent": { - "$ref": "#/definitions/color_value" - }, - "background": { - "$ref": "#/definitions/color_value" - }, - "primary": { - "$ref": "#/definitions/color_value" + "type": { + "$ref": "enums/brand-agent-type.json", + "description": "Functional role of this agent" }, - "secondary": { - "$ref": "#/definitions/color_value" + "url": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "Agent endpoint URL (MCP or A2A)" }, - "text": { - "$ref": "#/definitions/color_value" - } - }, - "type": "object" - }, - "colorway": { - "additionalProperties": true, - "description": "A named color pairing that defines how colors work together. Colorways ensure foreground/background combinations are always on-brand and accessible.", - "properties": { - "accent": { - "$ref": "#/definitions/hex_color" + "id": { + "type": "string", + "description": "Agent identifier (useful for logging, multi-tenant platforms)", + "pattern": "^[a-z0-9_]+$", + "maxLength": 100 }, - "background": { - "$ref": "#/definitions/hex_color" + "description": { + "type": "string", + "description": "Human-readable description of this agent's capabilities or scope", + "maxLength": 500 }, - "border": { - "$ref": "#/definitions/hex_color" + "jwks_uri": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "HTTPS URL of the agent's JWKS (RFC 7517) containing public keys used to verify artifacts this agent signs or requests it sends. Verified artifacts include signed governance_context tokens (for governance agents) and RFC 9421 HTTP Signatures on outgoing requests (for any agent). When absent, verifiers MUST default to /.well-known/jwks.json on the origin of `url`. Keys are identified by `kid` in the JWS header or RFC 9421 `keyid` parameter; JWKS MAY contain multiple keys to support rotation and per-purpose separation via `key_ops` and `use`." }, - "channels": { - "description": "Channels or contexts where this colorway applies (e.g., 'online', 'print', 'pos', 'social', 'outdoor'). Omit for universal colorways.", + "scope": { + "type": "array", + "description": "For governance agents: which governance responsibilities this agent handles. Values correspond to compliance specialisms. When a house declares multiple governance agents, scope distinguishes them. When absent on a governance agent, the agent is assumed to handle all governance categories.", "items": { - "type": "string" + "type": "string", + "enum": [ + "spend_authority", + "delivery_monitor", + "brand_safety", + "regulatory_compliance" + ] }, - "type": "array" - }, - "cta_background": { - "$ref": "#/definitions/hex_color", - "description": "CTA button/container color, if different from accent" + "uniqueItems": true }, - "cta_foreground": { - "$ref": "#/definitions/hex_color", - "description": "CTA text/icon color, if different from foreground" + "available_uses": { + "type": "array", + "description": "For rights agents: rights uses available for licensing", + "items": { + "$ref": "enums/right-use.json" + }, + "minItems": 1 }, - "foreground": { - "$ref": "#/definitions/hex_color" + "right_types": { + "type": "array", + "description": "For rights agents: types of rights available", + "items": { + "$ref": "enums/right-type.json" + }, + "minItems": 1 }, - "name": { - "description": "Colorway name (e.g., 'primary', 'inverted', 'subtle')", - "type": "string" + "countries": { + "type": "array", + "description": "ISO 3166-1 alpha-2 country codes where this agent operates. Omit for global scope.", + "items": { + "type": "string", + "pattern": "^[A-Z]{2}$" + } } }, "required": [ - "name", - "foreground", - "background" + "type", + "url", + "id" ], - "type": "object" + "additionalProperties": true }, - "composition_rules": { - "additionalProperties": true, - "description": "Layout composition rules including overlays, textures, and backgrounds", + "agents": { + "type": "array", + "description": "Agents declared by this brand or house. One agent per type.", + "items": { + "$ref": "#/definitions/brand_agent_entry" + }, + "maxItems": 20 + }, + "authorized_operator": { + "type": "object", + "description": "An entity authorized to represent brands from this house. Verified by resolving the operator's domain.", "properties": { - "backgrounds": { - "additionalProperties": true, - "description": "Background treatment rules", - "properties": { - "types_allowed": { - "description": "Permitted background types", - "items": { - "enum": [ - "solid_color", - "gradient", - "blurred_photo", - "image", - "video", - "pattern", - "transparent" - ], - "type": "string" - }, - "type": "array" - } + "domain": { + "$ref": "#/definitions/domain", + "description": "Domain of the authorized operator (e.g., 'groupm.com')" + }, + "brands": { + "type": "array", + "description": "Brand IDs this operator is authorized for. Use ['*'] for all brands in the portfolio.", + "items": { + "type": "string", + "pattern": "^([a-z0-9_]+|\\*)$" }, - "type": "object" + "minItems": 1 }, - "overlays": { - "additionalProperties": true, - "description": "Graphic overlay rules", + "countries": { + "type": "array", + "description": "ISO 3166-1 alpha-2 country codes where this authorization applies. Omit for global authorization.", + "items": { + "type": "string", + "pattern": "^[A-Z]{2}$" + } + } + }, + "required": [ + "domain", + "brands" + ], + "additionalProperties": true + }, + "photography_style": { + "type": "object", + "description": "Photography style rules for generative creative systems. Defines how brand photography should look when selected or generated.", + "properties": { + "realism": { + "type": "string", + "enum": [ + "natural", + "stylized", + "hyperreal", + "abstract" + ], + "description": "Level of photographic realism" + }, + "lighting": { + "type": "string", + "description": "Lighting style (e.g., 'soft daylight', 'studio', 'golden hour', 'high-key', 'low-key')" + }, + "color_temperature": { + "type": "string", + "enum": [ + "warm", + "neutral", + "cool" + ], + "description": "Overall color temperature of photography" + }, + "contrast": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "description": "Contrast level in photography" + }, + "depth_of_field": { + "type": "string", + "enum": [ + "shallow", + "medium", + "deep" + ], + "description": "Depth of field preference. shallow: blurred background with subject isolation, deep: everything in focus" + }, + "subject": { + "type": "object", + "description": "Subject matter guidelines", "properties": { - "gradient_direction": { - "description": "Gradient direction (e.g., '45deg', 'to-bottom-right')", - "type": "string" + "people": { + "type": "object", + "description": "People photography guidelines", + "properties": { + "age_range": { + "type": "string", + "description": "Target age range (e.g., '20-35')" + }, + "diversity": { + "type": "string", + "description": "Diversity representation (e.g., 'mixed', 'varied')" + }, + "mood": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Mood descriptors (e.g., ['confident', 'relaxed'])" + } + }, + "additionalProperties": true }, - "gradient_style": { - "description": "Gradient type for overlays", + "product_focus": { + "type": "string", "enum": [ - "linear", - "radial", - "conic", - "none" + "in-use", + "isolated", + "lifestyle", + "detail" ], - "type": "string" + "description": "How products are shown" }, - "opacity": { - "description": "Overlay opacity (e.g., '70%')", - "type": "string" + "setting": { + "type": "string", + "description": "Environmental context for photography (e.g., 'indoor', 'outdoor', 'studio', 'urban', 'nature', 'workplace')" } }, - "type": "object" + "additionalProperties": true }, - "texture": { - "additionalProperties": true, - "description": "Texture treatment rules", + "framing": { + "type": "object", + "description": "Camera framing rules", "properties": { - "intensity": { - "description": "Texture intensity", - "enum": [ - "low", - "medium", - "high" - ], - "type": "string" + "subject_position": { + "type": "string", + "description": "Where the subject sits in frame (e.g., 'center', 'center-left', 'rule-of-thirds')" }, - "style": { - "description": "Texture style applied to creative assets", - "enum": [ - "none", - "subtle_grain", - "noise", - "paper", - "fabric", - "concrete" - ], - "type": "string" + "crop_style": { + "type": "string", + "description": "Cropping convention (e.g., 'waist-up', 'full-body', 'close-up', 'wide')" + }, + "perspective": { + "type": "string", + "description": "Camera perspective (e.g., 'eye-level', 'overhead', 'low-angle')" } }, - "type": "object" - } - }, - "type": "object" - }, - "contact": { - "additionalProperties": true, - "description": "Contact information", - "properties": { - "domain": { - "$ref": "#/definitions/domain" - }, - "email": { - "format": "email", - "maxLength": 255, - "type": "string" + "additionalProperties": true }, - "name": { - "maxLength": 255, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "domain": { - "description": "A valid domain name", - "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", - "type": "string" - }, - "fonts": { - "additionalProperties": true, - "description": "Brand typography", - "properties": { - "font_urls": { - "description": "URLs to web font files", + "preferred_aspect_ratios": { + "type": "array", "items": { - "format": "uri", - "type": "string" + "type": "string", + "pattern": "^\\d+:\\d+$" }, - "type": "array" - }, - "primary": { - "description": "Primary font family", - "type": "string" + "description": "Preferred aspect ratios for brand photography (e.g., '16:9', '4:5', '1:1')" }, - "secondary": { - "description": "Secondary font family", - "type": "string" - } - }, - "type": "object" - }, - "graphic_element": { - "additionalProperties": true, - "description": "A reusable decorative or structural visual element that is part of the brand identity (e.g., torn paper edges, watermarks, dividers, background patterns)", - "properties": { - "colors": { - "description": "Colors this element may appear in", + "tags": { + "type": "array", "items": { - "$ref": "#/definitions/hex_color" + "type": "string" }, - "type": "array" - }, - "description": { - "description": "How the element is used in layouts", - "type": "string" - }, - "max_per_layout": { - "description": "Maximum instances per layout", - "type": "integer" - }, - "name": { - "description": "Element name (e.g., 'Paper Tear', 'Brand Watermark', 'Section Divider')", - "type": "string" - }, - "orientation": { - "description": "Preferred orientation when used in layouts", - "enum": [ - "horizontal", - "vertical", - "any" - ], - "type": "string" - }, - "type": { - "description": "Element type", - "enum": [ - "border", - "divider", - "frame", - "watermark", - "pattern", - "texture_overlay", - "decorative" - ], - "type": "string" + "description": "Additional style descriptors" } }, - "required": [ - "name" - ], - "type": "object" + "additionalProperties": true }, "graphic_style": { - "additionalProperties": true, + "type": "object", "description": "Visual language for brand graphics and illustrations", "properties": { - "corner_radius": { - "description": "Default corner radius for rounded elements (e.g., '12px', '8px', 'sharp')", - "type": "string" - }, - "stroke_style": { - "description": "Stroke end/join style", - "enum": [ - "rounded", - "square", - "mixed", - "none" - ], - "type": "string" - }, - "stroke_weight": { - "description": "Stroke weight (e.g., '2px', 'thin', 'bold')", - "type": "string" - }, "style_type": { - "description": "Primary graphic style", + "type": "string", "enum": [ "flat_illustration", "geometric", @@ -789,78 +1107,173 @@ "isometric", "photographic_composite" ], - "type": "string" + "description": "Primary graphic style" + }, + "stroke_style": { + "type": "string", + "enum": [ + "rounded", + "square", + "mixed", + "none" + ], + "description": "Stroke end/join style" + }, + "stroke_weight": { + "type": "string", + "description": "Stroke weight (e.g., '2px', 'thin', 'bold')" + }, + "corner_radius": { + "type": "string", + "description": "Default corner radius for graphic and illustration elements (e.g., '12px', '8px', 'sharp'). For UI component radii (buttons, cards, inputs), see visual_guidelines.border_radius." }, "tags": { - "description": "Additional style descriptors", + "type": "array", "items": { "type": "string" }, - "type": "array" + "description": "Additional style descriptors" } }, - "type": "object" - }, - "hex_color": { - "description": "A single hex color value", - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "additionalProperties": true }, - "house": { - "additionalProperties": true, - "description": "Corporate or organizational entity that owns brands", + "border_radius": { + "type": "object", + "description": "Named border radius presets for UI components and layout elements. One of the most visible brand differentiators \u2014 Airbnb uses generous 20px, Stripe uses precise 4\u20138px, Spotify uses pill/999px.", "properties": { - "architecture": { - "description": "Brand architecture model: branded_house (Google), house_of_brands (P&G), hybrid (Nike)", - "enum": [ - "branded_house", - "house_of_brands", - "hybrid" - ], - "type": "string" + "none": { + "type": "string", + "description": "Explicitly sharp corners (e.g., '0')" }, - "domain": { - "$ref": "#/definitions/domain", - "description": "The house's domain where brand.json is hosted" + "default": { + "type": "string", + "description": "Default border radius for UI components (e.g., '8px', '12px', '0'). For graphic/illustration elements, see graphic_style.corner_radius." }, - "name": { - "description": "Primary display name of the house", - "minLength": 1, - "type": "string" + "small": { + "type": "string", + "description": "Small border radius for compact elements (e.g., '4px')" }, - "names": { - "description": "Localized house names including legal name, stock symbol, etc.", - "items": { - "$ref": "#/definitions/localized_name" - }, - "type": "array" + "large": { + "type": "string", + "description": "Large border radius for cards and containers (e.g., '16px', '24px')" + }, + "pill": { + "type": "string", + "description": "Fully rounded / pill shape (e.g., '999px')" } }, - "required": [ - "domain", - "name" - ], - "type": "object" + "additionalProperties": { + "type": "string" + } }, - "iconography": { - "additionalProperties": true, - "description": "Icon style system and usage rules", + "elevation": { + "type": "object", + "description": "Named shadow/elevation levels. Brands use elevation as identity \u2014 from Stripe's blue-tinted multi-layer shadows to Apple's single diffuse shadow. Values are CSS box-shadow syntax.", "properties": { - "corner_style": { - "description": "Corner style for icon paths", - "enum": [ - "rounded", - "square", - "mixed" - ], - "type": "string" + "none": { + "type": "string", + "description": "No shadow (e.g., 'none')" }, - "stroke_weight": { - "description": "Icon stroke weight (e.g., '2px', '1.5px')", - "type": "string" + "subtle": { + "type": "string", + "description": "Subtle shadow for slight lift (e.g., '0 1px 2px rgba(0,0,0,0.05)')" + }, + "card": { + "type": "string", + "description": "Card-level shadow (e.g., '0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)')" + }, + "modal": { + "type": "string", + "description": "Modal/overlay shadow (e.g., '0 20px 25px -5px rgba(0,0,0,0.1), 0 8px 10px -6px rgba(0,0,0,0.1)')" + } + }, + "additionalProperties": { + "type": "string" + } + }, + "spacing": { + "type": "object", + "description": "Spacing system for consistent layout rhythm. Most design systems use an 8px base grid.", + "properties": { + "unit": { + "type": "string", + "description": "Base grid unit this scale was designed from (e.g., '8px', '4px'). Informational \u2014 agents should use the named scale values, not compute from this." + }, + "scale": { + "type": "object", + "description": "Named spacing scale built from the base unit", + "properties": { + "xs": { + "type": "string", + "description": "Extra small spacing (e.g., '4px')" + }, + "sm": { + "type": "string", + "description": "Small spacing (e.g., '8px')" + }, + "md": { + "type": "string", + "description": "Medium spacing (e.g., '16px')" + }, + "lg": { + "type": "string", + "description": "Large spacing (e.g., '24px')" + }, + "xl": { + "type": "string", + "description": "Extra large spacing (e.g., '32px')" + }, + "2xl": { + "type": "string", + "description": "Section-level spacing (e.g., '48px', '64px')" + } + }, + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "brand_shapes": { + "type": "object", + "description": "Distinctive shapes used as part of brand visual identity", + "properties": { + "primary_shape": { + "type": "string", + "description": "Primary brand shape (e.g., 'rounded_rectangle', 'circle', 'hexagon')" + }, + "secondary_shapes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Secondary shapes in the brand vocabulary" }, + "usage": { + "type": "object", + "description": "Shape usage rules", + "properties": { + "max_per_layout": { + "type": "integer", + "description": "Maximum distinct shapes per layout" + }, + "overlap_allowed": { + "type": "boolean", + "description": "Whether shapes may overlap" + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "iconography": { + "type": "object", + "description": "Icon style system and usage rules", + "properties": { "style": { - "description": "Icon rendering style", + "type": "string", "enum": [ "outline", "filled", @@ -869,186 +1282,233 @@ "glyph", "hand_drawn" ], - "type": "string" + "description": "Icon rendering style" + }, + "stroke_weight": { + "type": "string", + "description": "Icon stroke weight (e.g., '2px', '1.5px')" + }, + "corner_style": { + "type": "string", + "enum": [ + "rounded", + "square", + "mixed" + ], + "description": "Corner style for icon paths" }, "usage": { - "additionalProperties": true, + "type": "object", "description": "Icon usage rules", "properties": { "max_per_frame": { - "description": "Maximum icons per creative frame", - "type": "integer" + "type": "integer", + "description": "Maximum icons per creative frame" }, "size_ratio": { - "description": "Icon-to-layout size ratio (e.g., '1:8')", - "type": "string" + "type": "string", + "description": "Icon-to-layout size ratio (e.g., '1:8')" } }, - "type": "object" + "additionalProperties": true } }, - "type": "object" + "additionalProperties": true }, - "keller_type": { - "description": "Brand architecture type from Keller's theory. master: primary brand of house. sub_brand: carries parent name (Nike SB). endorsed: independent identity backed by parent (Air Jordan 'by Nike'). independent: operates separately (Converse under Nike, Inc.)", - "enum": [ - "master", - "sub_brand", - "endorsed", - "independent" - ], - "type": "string" - }, - "localized_name": { - "additionalProperties": { - "minLength": 1, - "type": "string" + "composition_rules": { + "type": "object", + "description": "Layout composition rules including overlays, textures, and backgrounds", + "properties": { + "overlays": { + "type": "object", + "description": "Graphic overlay rules", + "properties": { + "gradient_style": { + "type": "string", + "enum": [ + "linear", + "radial", + "conic", + "none" + ], + "description": "Gradient type for overlays" + }, + "gradient_direction": { + "type": "string", + "description": "Gradient direction (e.g., '45deg', 'to-bottom-right')" + }, + "opacity": { + "type": "string", + "description": "Overlay opacity (e.g., '70%')" + } + }, + "additionalProperties": true + }, + "texture": { + "type": "object", + "description": "Texture treatment rules", + "properties": { + "style": { + "type": "string", + "enum": [ + "none", + "subtle_grain", + "noise", + "paper", + "fabric", + "concrete" + ], + "description": "Texture style applied to creative assets" + }, + "intensity": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "description": "Texture intensity" + } + }, + "additionalProperties": true + }, + "backgrounds": { + "type": "object", + "description": "Background treatment rules", + "properties": { + "types_allowed": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "solid_color", + "gradient", + "blurred_photo", + "image", + "video", + "pattern", + "transparent" + ] + }, + "description": "Permitted background types" + } + }, + "additionalProperties": true + } }, - "description": "A localized name with BCP 47 locale code key (e.g., 'en_US', 'fr_CA', 'zh_CN') and name value. Bare language codes ('en') are accepted as wildcards for backwards compatibility.", - "maxProperties": 1, - "minProperties": 1, - "type": "object" + "additionalProperties": true }, - "logo": { - "additionalProperties": true, - "description": "Brand logo asset with structured fields for orientation, background compatibility, and variant type", + "colorway": { + "type": "object", + "description": "A named color pairing that defines how colors work together. Colorways ensure foreground/background combinations are always on-brand and accessible.", "properties": { - "background": { - "description": "Background compatibility. dark-bg: use on dark backgrounds, light-bg: use on light backgrounds, transparent-bg: has transparent background", - "enum": [ - "dark-bg", - "light-bg", - "transparent-bg" - ], - "type": "string" + "name": { + "type": "string", + "description": "Colorway name (e.g., 'primary', 'inverted', 'subtle')" }, - "height": { - "description": "Height in pixels", - "type": "integer" + "foreground": { + "$ref": "#/definitions/hex_color" }, - "orientation": { - "description": "Logo aspect ratio orientation. square: ~1:1, horizontal: wide, vertical: tall, stacked: vertically arranged elements", - "enum": [ - "square", - "horizontal", - "vertical", - "stacked" - ], - "type": "string" + "background": { + "$ref": "#/definitions/hex_color" }, - "tags": { - "description": "Additional semantic tags for custom categorization beyond the standard orientation, background, and variant fields", - "items": { - "type": "string" - }, - "type": "array" + "accent": { + "$ref": "#/definitions/hex_color" }, - "url": { - "description": "URL to the logo asset", - "format": "uri", - "type": "string" + "border": { + "$ref": "#/definitions/hex_color" }, - "usage": { - "description": "Human-readable description of when to use this logo variant (e.g., 'Primary logo for use on light backgrounds')", - "type": "string" + "cta_foreground": { + "$ref": "#/definitions/hex_color", + "description": "CTA text/icon color, if different from foreground" }, - "variant": { - "description": "Logo variant type. primary: main logo, secondary: alternative, icon: symbol only, wordmark: text only, full-lockup: complete logo", - "enum": [ - "primary", - "secondary", - "icon", - "wordmark", - "full-lockup" - ], - "type": "string" + "cta_background": { + "$ref": "#/definitions/hex_color", + "description": "CTA button/container color, if different from accent" }, - "width": { - "description": "Width in pixels", - "type": "integer" + "channels": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Channels or contexts where this colorway applies (e.g., 'online', 'print', 'pos', 'social', 'outdoor'). Omit for universal colorways." } }, "required": [ - "url" + "name", + "foreground", + "background" ], - "type": "object" + "additionalProperties": true }, - "logo_placement": { - "additionalProperties": true, - "description": "Logo placement and clear space rules for automated creative production", + "type_scale_entry": { + "type": "object", + "description": "A single entry in the type scale", "properties": { - "background_contrast": { - "description": "Permitted background contrast behind logo", - "enum": [ - "light_only", - "dark_only", - "any" - ], - "type": "string" + "font": { + "type": "string", + "description": "Font reference. Use a key from the fonts object (e.g., 'primary', 'secondary') to reference a defined font role, or a literal CSS font-family string as a fallback." }, - "min_clear_space": { - "description": "Minimum clear space around the logo, expressed as a multiple of logo height (e.g., '0.5x', '1x') or fixed value (e.g., '16px')", - "type": "string" + "size": { + "type": "string", + "description": "Font size (e.g., '48px', '2rem')" }, - "min_height": { - "description": "Minimum logo height to maintain legibility (e.g., '40px', '24px')", - "type": "string" + "weight": { + "type": "string", + "description": "Font weight (e.g., '700', 'bold')" }, - "preferred_position": { - "description": "Preferred logo position in layouts", + "line_height": { + "type": "string", + "description": "Line height (e.g., '1.2', '56px')" + }, + "letter_spacing": { + "type": "string", + "description": "Letter spacing (e.g., '-0.02em', '0.5px')" + }, + "text_transform": { + "type": "string", "enum": [ - "top-left", - "top-center", - "top-right", - "bottom-left", - "bottom-center", - "bottom-right", - "center" + "none", + "uppercase", + "lowercase", + "capitalize" ], - "type": "string" + "description": "Text transformation" } }, - "type": "object" + "additionalProperties": true }, "motion_guidelines": { - "additionalProperties": true, + "type": "object", "description": "Motion and animation rules for video, animated display, and interactive formats", "properties": { + "transition_style": { + "type": "string", + "enum": [ + "cut", + "dissolve", + "slide", + "wipe", + "zoom", + "fade" + ], + "description": "Primary transition style between scenes" + }, "animation_speed": { - "description": "Overall animation pacing", + "type": "string", "enum": [ "slow", "moderate", "fast" ], - "type": "string" + "description": "Overall animation pacing" }, "easing": { - "description": "Default easing function (e.g., 'ease-in-out', 'spring', 'linear')", - "type": "string" - }, - "kinetic_typography": { - "description": "Whether animated/kinetic typography is allowed", - "type": "boolean" + "type": "string", + "description": "Default easing function (e.g., 'ease-in-out', 'spring', 'linear')" }, - "pacing": { - "description": "Overall editing rhythm", - "enum": [ - "lingering", - "moderate", - "fast_cuts" - ], - "type": "string" - }, - "tags": { - "description": "Additional motion style descriptors", - "items": { - "type": "string" - }, - "type": "array" - }, - "text_entrance": { - "description": "How text enters the frame", + "text_entrance": { + "type": "string", "enum": [ "fade", "typewriter", @@ -1057,621 +1517,592 @@ "scale", "none" ], - "type": "string" + "description": "How text enters the frame" }, - "transition_style": { - "description": "Primary transition style between scenes", + "pacing": { + "type": "string", "enum": [ - "cut", - "dissolve", - "slide", - "wipe", - "zoom", - "fade" + "lingering", + "moderate", + "fast_cuts" ], - "type": "string" + "description": "Overall editing rhythm" + }, + "kinetic_typography": { + "type": "boolean", + "description": "Whether animated/kinetic typography is allowed" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional motion style descriptors" } }, - "type": "object" + "additionalProperties": true }, - "photography_style": { - "additionalProperties": true, - "description": "Photography style rules for generative creative systems. Defines how brand photography should look when selected or generated.", + "logo_placement": { + "type": "object", + "description": "Logo placement and clear space rules for automated creative production", "properties": { - "color_temperature": { - "description": "Overall color temperature of photography", + "preferred_position": { + "type": "string", "enum": [ - "warm", - "neutral", - "cool" + "top-left", + "top-center", + "top-right", + "bottom-left", + "bottom-center", + "bottom-right", + "center" ], - "type": "string" + "description": "Preferred logo position in layouts" }, - "contrast": { - "description": "Contrast level in photography", + "min_clear_space": { + "type": "string", + "description": "Minimum clear space around the logo, expressed as a multiple of logo height (e.g., '0.5x', '1x') or fixed value (e.g., '16px')" + }, + "min_height": { + "type": "string", + "description": "Minimum logo height to maintain legibility (e.g., '40px', '24px')" + }, + "background_contrast": { + "type": "string", "enum": [ - "low", - "medium", - "high" + "light_only", + "dark_only", + "any" ], - "type": "string" + "description": "Permitted background contrast behind logo" + } + }, + "additionalProperties": true + }, + "graphic_element": { + "type": "object", + "description": "A reusable decorative or structural visual element that is part of the brand identity (e.g., torn paper edges, watermarks, dividers, background patterns)", + "properties": { + "name": { + "type": "string", + "description": "Element name (e.g., 'Paper Tear', 'Brand Watermark', 'Section Divider')" }, - "depth_of_field": { - "description": "Depth of field preference. shallow: blurred background with subject isolation, deep: everything in focus", + "type": { + "type": "string", "enum": [ - "shallow", - "medium", - "deep" + "border", + "divider", + "frame", + "watermark", + "pattern", + "texture_overlay", + "decorative" ], - "type": "string" - }, - "framing": { - "additionalProperties": true, - "description": "Camera framing rules", - "properties": { - "crop_style": { - "description": "Cropping convention (e.g., 'waist-up', 'full-body', 'close-up', 'wide')", - "type": "string" - }, - "perspective": { - "description": "Camera perspective (e.g., 'eye-level', 'overhead', 'low-angle')", - "type": "string" - }, - "subject_position": { - "description": "Where the subject sits in frame (e.g., 'center', 'center-left', 'rule-of-thirds')", - "type": "string" - } - }, - "type": "object" - }, - "lighting": { - "description": "Lighting style (e.g., 'soft daylight', 'studio', 'golden hour', 'high-key', 'low-key')", - "type": "string" + "description": "Element type" }, - "preferred_aspect_ratios": { - "description": "Preferred aspect ratios for brand photography (e.g., '16:9', '4:5', '1:1')", - "items": { - "pattern": "^\\d+:\\d+$", - "type": "string" - }, - "type": "array" + "description": { + "type": "string", + "description": "How the element is used in layouts" }, - "realism": { - "description": "Level of photographic realism", + "orientation": { + "type": "string", "enum": [ - "natural", - "stylized", - "hyperreal", - "abstract" + "horizontal", + "vertical", + "any" ], - "type": "string" + "description": "Preferred orientation when used in layouts" }, - "subject": { - "additionalProperties": true, - "description": "Subject matter guidelines", - "properties": { - "people": { - "additionalProperties": true, - "description": "People photography guidelines", - "properties": { - "age_range": { - "description": "Target age range (e.g., '20-35')", - "type": "string" - }, - "diversity": { - "description": "Diversity representation (e.g., 'mixed', 'varied')", - "type": "string" - }, - "mood": { - "description": "Mood descriptors (e.g., ['confident', 'relaxed'])", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "product_focus": { - "description": "How products are shown", - "enum": [ - "in-use", - "isolated", - "lifestyle", - "detail" - ], - "type": "string" - }, - "setting": { - "description": "Environmental context for photography (e.g., 'indoor', 'outdoor', 'studio', 'urban', 'nature', 'workplace')", - "type": "string" - } - }, - "type": "object" - }, - "tags": { - "description": "Additional style descriptors", + "colors": { + "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/hex_color" }, - "type": "array" + "description": "Colors this element may appear in" + }, + "max_per_layout": { + "type": "integer", + "description": "Maximum instances per layout" } }, - "type": "object" + "required": [ + "name" + ], + "additionalProperties": true }, - "product_catalog": { - "additionalProperties": true, - "description": "Product catalog for e-commerce brands", + "asset_library": { + "type": "object", + "description": "A managed asset library (icon set, illustration system, image collection). The URL is for human access; agent-facing DAM integration is under investigation.", "properties": { - "agentic_checkout": { - "description": "Agentic checkout endpoint configuration", - "properties": { - "endpoint": { - "description": "Base URL for checkout session API", - "format": "uri", - "type": "string" - }, - "spec": { - "description": "Checkout API specification", - "enum": [ - "openai_agentic_checkout_v1" - ], - "type": "string" - }, - "supported_payment_providers": { - "description": "Payment providers supported by this checkout endpoint", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "endpoint", - "spec" - ], - "type": "object" - }, - "categories": { - "description": "Product categories available in the catalog", - "items": { - "type": "string" - }, - "type": "array" + "name": { + "type": "string", + "description": "Display name of the asset library" }, - "feed_format": { - "description": "Format of the product feed", + "type": { + "type": "string", "enum": [ - "google_merchant_center", - "facebook_catalog", - "openai_product_feed", - "custom" + "icon_set", + "illustration_system", + "image_library", + "video_library", + "template_library" ], - "type": "string" + "description": "Type of asset library" }, - "feed_url": { - "description": "URL to product catalog feed", + "url": { + "type": "string", "format": "uri", - "type": "string" + "description": "URL to the asset library (for human access)" }, - "last_updated": { - "description": "When the product catalog was last updated", - "format": "date-time", - "type": "string" + "description": { + "type": "string", + "description": "Description of the library contents and usage" }, - "update_frequency": { - "description": "How frequently the product catalog is updated", - "enum": [ - "realtime", - "hourly", - "daily", - "weekly" - ], - "type": "string" + "color_guide": { + "type": "object", + "description": "Color guide for the asset library defining roles and palettes", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Named color roles used in the library (e.g., base, shadow_1, highlight_1, stroke)" + }, + "palettes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Palette name" + }, + "colors": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/hex_color" + }, + "description": "Map of role names to hex color values" + } + }, + "required": [ + "name", + "colors" + ], + "additionalProperties": true + }, + "description": "Named color palettes mapping roles to specific colors" + } + }, + "additionalProperties": true } }, "required": [ - "feed_url" + "name", + "url" ], - "type": "object" + "additionalProperties": true }, - "property": { - "additionalProperties": true, - "description": "A digital property owned by a brand", + "visual_guidelines": { + "type": "object", + "description": "Structured visual rules for generative creative systems. Defines how brand photography, graphics, typography, and composition should be produced to maintain brand consistency at scale.", "properties": { - "identifier": { - "description": "Property identifier - domain for websites, bundle ID for apps", - "minLength": 1, - "type": "string" + "photography": { + "$ref": "#/definitions/photography_style" }, - "primary": { - "default": false, - "description": "Whether this is the primary property for the brand", - "type": "boolean" + "graphic_style": { + "$ref": "#/definitions/graphic_style" }, - "region": { - "description": "ISO 3166-1 alpha-2 country code or 'global'", - "pattern": "^([A-Z]{2}|global)$", - "type": "string" + "shapes": { + "$ref": "#/definitions/brand_shapes" }, - "store": { - "description": "App store for mobile/CTV apps", - "enum": [ - "apple", - "google", - "amazon", - "roku", - "samsung", - "lg", - "other" - ], - "type": "string" + "iconography": { + "$ref": "#/definitions/iconography" }, - "type": { - "description": "Property type", - "enum": [ - "website", - "mobile_app", - "ctv_app", - "desktop_app", - "dooh", - "podcast", - "radio", - "streaming_audio" - ], - "type": "string" - } - }, - "required": [ - "type", - "identifier" - ], - "type": "object" - }, - "rights_agent": { - "additionalProperties": true, - "description": "Rights licensing agent for this brand. Provides discovery, pricing, and acquisition of licensable rights via MCP. Use get_rights and acquire_rights tasks to interact.", - "properties": { - "available_uses": { - "description": "Rights uses available for licensing through this agent", + "composition": { + "$ref": "#/definitions/composition_rules" + }, + "border_radius": { + "$ref": "#/definitions/border_radius" + }, + "elevation": { + "$ref": "#/definitions/elevation" + }, + "spacing": { + "$ref": "#/definitions/spacing" + }, + "graphic_elements": { + "type": "array", + "items": { + "$ref": "#/definitions/graphic_element" + }, + "description": "Reusable decorative elements that are part of the brand visual identity (e.g., torn paper edges, watermarks, dividers)" + }, + "motion": { + "$ref": "#/definitions/motion_guidelines" + }, + "logo_placement": { + "$ref": "#/definitions/logo_placement" + }, + "colorways": { + "type": "array", + "items": { + "$ref": "#/definitions/colorway" + }, + "description": "Named color pairings for consistent foreground/background combinations" + }, + "type_scale": { + "type": "object", + "description": "Typography scale defining sizes and weights for different text roles. When sizes are in px, use base_width to indicate the reference canvas.", + "properties": { + "base_width": { + "type": "string", + "description": "Reference canvas width these sizes were designed for (e.g., '1080px'). Generative systems should scale proportionally for other canvas sizes." + }, + "heading": { + "$ref": "#/definitions/type_scale_entry" + }, + "subheading": { + "$ref": "#/definitions/type_scale_entry" + }, + "body": { + "$ref": "#/definitions/type_scale_entry" + }, + "caption": { + "$ref": "#/definitions/type_scale_entry" + }, + "cta": { + "$ref": "#/definitions/type_scale_entry" + } + }, + "additionalProperties": { + "$ref": "#/definitions/type_scale_entry" + } + }, + "asset_libraries": { + "type": "array", "items": { - "$ref": "enums/right-use.json" + "$ref": "#/definitions/asset_library" }, - "minItems": 1, - "type": "array" + "description": "References to managed asset libraries (icon sets, illustration systems, image collections). URLs are intended for human access; agent-facing DAM integration is under investigation." }, - "countries": { - "description": "Countries where rights are available (ISO 3166-1 alpha-2)", + "restrictions": { + "type": "array", "items": { - "pattern": "^[A-Z]{2}$", "type": "string" }, - "type": "array" + "description": "Visual prohibitions and guardrails (e.g., 'Never use black backgrounds', 'Do not crop the logo', 'No stock photography of people on phones')" + } + }, + "additionalProperties": true + }, + "contact": { + "type": "object", + "description": "Contact information", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255 }, - "id": { - "description": "Agent identifier", - "pattern": "^[a-z0-9_]+$", - "type": "string" + "email": { + "type": "string", + "format": "email", + "maxLength": 255 }, - "right_types": { - "description": "Types of rights available", - "items": { - "$ref": "enums/right-type.json" - }, - "minItems": 1, - "type": "array" + "domain": { + "$ref": "#/definitions/domain" + } + }, + "required": [ + "name" + ], + "additionalProperties": true + } + }, + "oneOf": [ + { + "type": "object", + "title": "Authoritative Location Redirect", + "description": "Redirects to a hosted brand.json file at another URL", + "properties": { + "$schema": { + "type": "string" }, - "url": { - "description": "Rights agent MCP endpoint URL", + "authoritative_location": { + "type": "string", "format": "uri", "pattern": "^https://", - "type": "string" + "description": "HTTPS URL of the authoritative brand.json file" + }, + "last_updated": { + "type": "string", + "format": "date-time" } }, "required": [ - "url", - "id", - "available_uses" + "authoritative_location" ], - "type": "object" + "additionalProperties": false }, - "type_scale_entry": { - "additionalProperties": true, - "description": "A single entry in the type scale", + { + "type": "object", + "title": "House Redirect", + "description": "Redirects to the house domain that contains the full brand portfolio", "properties": { - "font": { - "description": "Font family reference (e.g., 'primary', 'secondary', or a specific family name)", - "type": "string" - }, - "letter_spacing": { - "description": "Letter spacing (e.g., '-0.02em', '0.5px')", + "$schema": { "type": "string" }, - "line_height": { - "description": "Line height (e.g., '1.2', '56px')", - "type": "string" + "house": { + "$ref": "#/definitions/domain", + "description": "House domain to fetch brand portfolio from" }, - "size": { - "description": "Font size (e.g., '48px', '2rem')", - "type": "string" + "region": { + "type": "string", + "pattern": "^[A-Z]{2}$", + "description": "ISO 3166-1 alpha-2 country code if this is a regional domain" }, - "text_transform": { - "description": "Text transformation", - "enum": [ - "none", - "uppercase", - "lowercase", - "capitalize" - ], + "note": { "type": "string" }, - "weight": { - "description": "Font weight (e.g., '700', 'bold')", - "type": "string" + "last_updated": { + "type": "string", + "format": "date-time" } }, - "type": "object" + "required": [ + "house" + ], + "additionalProperties": false }, - "visual_guidelines": { - "additionalProperties": true, - "description": "Structured visual rules for generative creative systems. Defines how brand photography, graphics, typography, and composition should be produced to maintain brand consistency at scale.", + { + "type": "object", + "title": "Brand Agent", + "description": "Brand represented by agents that provide brand info via MCP", "properties": { - "asset_libraries": { - "description": "References to managed asset libraries (icon sets, illustration systems, image collections). URLs are intended for human access; agent-facing DAM integration is under investigation.", - "items": { - "$ref": "#/definitions/asset_library" - }, - "type": "array" + "$schema": { + "type": "string" }, - "colorways": { - "description": "Named color pairings for consistent foreground/background combinations", - "items": { - "$ref": "#/definitions/colorway" - }, - "type": "array" + "version": { + "type": "string" }, - "composition": { - "$ref": "#/definitions/composition_rules" + "agents": { + "$ref": "#/definitions/agents" }, - "graphic_elements": { - "description": "Reusable decorative elements that are part of the brand visual identity (e.g., torn paper edges, watermarks, dividers)", - "items": { - "$ref": "#/definitions/graphic_element" - }, - "type": "array" + "brand_agent": { + "$ref": "#/definitions/brand_agent", + "deprecated": true }, - "graphic_style": { - "$ref": "#/definitions/graphic_style" + "contact": { + "$ref": "#/definitions/contact" }, - "iconography": { - "$ref": "#/definitions/iconography" + "last_updated": { + "type": "string", + "format": "date-time" + } + }, + "anyOf": [ + { + "required": [ + "agents" + ] }, - "logo_placement": { - "$ref": "#/definitions/logo_placement" + { + "required": [ + "brand_agent" + ] + } + ], + "additionalProperties": false + }, + { + "type": "object", + "title": "House Portfolio", + "description": "Full house/brand portfolio with hierarchy, creative assets, and properties", + "properties": { + "$schema": { + "type": "string" }, - "motion": { - "$ref": "#/definitions/motion_guidelines" + "version": { + "type": "string" }, - "photography": { - "$ref": "#/definitions/photography_style" + "house": { + "$ref": "#/definitions/house" }, - "restrictions": { - "description": "Visual prohibitions and guardrails (e.g., 'Never use black backgrounds', 'Do not crop the logo', 'No stock photography of people on phones')", + "brands": { + "type": "array", + "description": "Brands owned by this house", "items": { - "type": "string" + "$ref": "#/definitions/brand" }, - "type": "array" + "minItems": 1 }, - "shapes": { - "$ref": "#/definitions/brand_shapes" + "contact": { + "$ref": "#/definitions/contact" }, - "type_scale": { - "additionalProperties": { - "$ref": "#/definitions/type_scale_entry" - }, - "description": "Typography scale defining sizes and weights for different text roles. When sizes are in px, use base_width to indicate the reference canvas.", - "properties": { - "base_width": { - "description": "Reference canvas width these sizes were designed for (e.g., '1080px'). Generative systems should scale proportionally for other canvas sizes.", - "type": "string" - }, - "body": { - "$ref": "#/definitions/type_scale_entry" - }, - "caption": { - "$ref": "#/definitions/type_scale_entry" - }, - "cta": { - "$ref": "#/definitions/type_scale_entry" - }, - "heading": { - "$ref": "#/definitions/type_scale_entry" + "authorized_operators": { + "type": "array", + "description": "Entities authorized to represent brands from this house. Third parties (sellers, platforms) can verify an operator's authorization by checking this list. Operators are identified by domain.", + "items": { + "$ref": "#/definitions/authorized_operator" + } + }, + "trademarks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "registry": { + "type": "string" + }, + "number": { + "type": "string" + }, + "mark": { + "type": "string" + } }, - "subheading": { - "$ref": "#/definitions/type_scale_entry" - } - }, - "type": "object" + "required": [ + "registry", + "number", + "mark" + ], + "additionalProperties": true + } + }, + "last_updated": { + "type": "string", + "format": "date-time" } }, - "type": "object" + "required": [ + "house", + "brands" + ], + "additionalProperties": false } - }, - "description": "Brand identity and discovery file. Hosted at /.well-known/brand.json on house domains. Contains the full brand portfolio with identity, creative assets, and digital properties. Brands are identified by house + brand_id (like properties are identified by publisher + property_id). Supports variants: house portfolio (full brand data), brand agent (agent provides brand info via MCP), house redirect (pointer to house domain), or authoritative location redirect.", + ], "examples": [ { - "$schema": "/schemas/3.0.0-rc.3/brand.json", + "$schema": "/schemas/latest/brand.json", "authoritative_location": "https://adcontextprotocol.org/brand/abc123/brand.json" }, { - "$schema": "/schemas/3.0.0-rc.3/brand.json", + "$schema": "/schemas/latest/brand.json", "house": "nikeinc.com", "note": "Redirect to house domain for full brand portfolio" }, { - "$schema": "/schemas/3.0.0-rc.3/brand.json", - "brand_agent": { - "id": "acme_brand_agent", - "url": "https://agent.acme.com/mcp" - }, - "version": "1.0" + "$schema": "/schemas/latest/brand.json", + "version": "1.0", + "agents": [ + { + "type": "brand", + "url": "https://agent.acme.com/mcp", + "id": "acme_brand" + } + ] }, { - "$schema": "/schemas/3.0.0-rc.3/brand.json", + "$schema": "/schemas/latest/brand.json", + "version": "1.0", + "house": { + "domain": "pg.com", + "name": "Procter & Gamble", + "architecture": "house_of_brands", + "agents": [ + { + "type": "governance", + "url": "https://agents.pg.com/governance", + "id": "pg_governance", + "description": "Brand safety and compliance for all P&G brands", + "jwks_uri": "https://agents.pg.com/.well-known/jwks.json", + "scope": [ + "spend_authority", + "delivery_monitor", + "brand_safety" + ] + } + ] + }, "brands": [ { - "colors": { - "primary": "#FF6600", - "secondary": "#0066CC" - }, - "contact": { - "email": "brands@pg.com" - }, - "description": "Laundry detergent brand", "id": "tide", - "industries": [ - "cpg" - ], - "keller_type": "master", - "logos": [ - { - "background": "transparent-bg", - "orientation": "square", - "url": "https://cdn.pg.com/tide/logo-square.png", - "usage": "Primary logo for general use", - "variant": "primary" - }, - { - "background": "dark-bg", - "orientation": "horizontal", - "url": "https://cdn.pg.com/tide/logo-horizontal-dark.png", - "usage": "Full lockup for dark backgrounds", - "variant": "full-lockup" - } - ], + "url": "https://tide.com", "names": [ { "en_US": "Tide" }, { - "es_MX": "Tide" - }, - { - "zh_CN": "\u6c70\u6e0d" - } - ], - "properties": [ - { - "identifier": "tide.com", - "primary": true, - "type": "website" + "es_MX": "Tide" }, { - "identifier": "com.pg.tide", - "store": "apple", - "type": "mobile_app" + "zh_CN": "\u6c70\u6e0d" } ], - "tagline": [ + "keller_type": "master", + "industries": [ + "cpg" + ], + "description": "Laundry detergent brand", + "logos": [ { - "en_US": "Tide's In, Dirt's Out" + "url": "https://cdn.pg.com/tide/logo-square.png", + "orientation": "square", + "background": "transparent-bg", + "variant": "primary", + "usage": "Primary logo for general use" + }, + { + "url": "https://cdn.pg.com/tide/logo-horizontal-dark.png", + "orientation": "horizontal", + "background": "dark-bg", + "variant": "full-lockup", + "usage": "Full lockup for dark backgrounds" } ], + "colors": { + "primary": "#FF6600", + "secondary": "#0066CC", + "background": "#FFFFFF", + "text": "#1A1A1A", + "heading": "#FF6600", + "body": "#333333", + "label": "#666666", + "border": "#E5E5E5", + "divider": "#F0F0F0", + "surface_1": "#F9F9F9", + "surface_2": "#EFEFEF" + }, "tone": { + "voice": "clean, fresh, trustworthy", "attributes": [ "reliable", "family-friendly", "confident" ], - "donts": [ - "Avoid technical jargon", - "Don't be overly serious" - ], "dos": [ "Use simple, direct language", "Emphasize cleaning power" ], - "voice": "clean, fresh, trustworthy" + "donts": [ + "Avoid technical jargon", + "Don't be overly serious" + ] }, - "url": "https://tide.com", + "tagline": [ + { + "en_US": "Tide's In, Dirt's Out" + } + ], "visual_guidelines": { - "colorways": [ - { - "accent": "#0066CC", - "background": "#FF6600", - "foreground": "#FFFFFF", - "name": "primary" - }, - { - "accent": "#0066CC", - "background": "#FFFFFF", - "border": "#FF6600", - "foreground": "#FF6600", - "name": "inverted" - } - ], - "composition": { - "backgrounds": { - "types_allowed": [ - "solid_color", - "gradient", - "blurred_photo" - ] - }, - "overlays": { - "gradient_direction": "180deg", - "gradient_style": "linear", - "opacity": "60%" - }, - "texture": { - "style": "none" - } - }, - "graphic_style": { - "corner_radius": "12px", - "stroke_style": "rounded", - "stroke_weight": "2px", - "style_type": "flat_illustration" - }, - "iconography": { - "corner_style": "rounded", - "stroke_weight": "2px", - "style": "outline", - "usage": { - "max_per_frame": 3, - "size_ratio": "1:8" - } - }, - "logo_placement": { - "background_contrast": "any", - "min_clear_space": "0.5x", - "min_height": "32px", - "preferred_position": "bottom-right" - }, - "motion": { - "animation_speed": "moderate", - "easing": "ease-in-out", - "kinetic_typography": false, - "pacing": "moderate", - "text_entrance": "fade", - "transition_style": "dissolve" - }, "photography": { + "realism": "natural", + "lighting": "soft daylight", "color_temperature": "warm", "contrast": "medium", "depth_of_field": "medium", - "framing": { - "crop_style": "waist-up", - "perspective": "eye-level", - "subject_position": "center" - }, - "lighting": "soft daylight", - "preferred_aspect_ratios": [ - "16:9", - "4:5", - "1:1" - ], - "realism": "natural", "subject": { "people": { "age_range": "25-45", @@ -1684,13 +2115,24 @@ }, "product_focus": "in-use", "setting": "indoor" - } + }, + "framing": { + "subject_position": "center", + "crop_style": "waist-up", + "perspective": "eye-level" + }, + "preferred_aspect_ratios": [ + "16:9", + "4:5", + "1:1" + ] + }, + "graphic_style": { + "style_type": "flat_illustration", + "stroke_style": "rounded", + "stroke_weight": "2px", + "corner_radius": "12px" }, - "restrictions": [ - "Never place text over the product", - "Do not use black backgrounds", - "No stock photography of people on phones" - ], "shapes": { "primary_shape": "circle", "secondary_shapes": [ @@ -1701,191 +2143,244 @@ "overlap_allowed": false } }, + "iconography": { + "style": "outline", + "stroke_weight": "2px", + "corner_style": "rounded", + "usage": { + "max_per_frame": 3, + "size_ratio": "1:8" + } + }, + "composition": { + "overlays": { + "gradient_style": "linear", + "gradient_direction": "180deg", + "opacity": "60%" + }, + "texture": { + "style": "none" + }, + "backgrounds": { + "types_allowed": [ + "solid_color", + "gradient", + "blurred_photo" + ] + } + }, + "border_radius": { + "none": "0", + "default": "12px", + "small": "4px", + "large": "20px", + "pill": "999px" + }, + "elevation": { + "none": "none", + "subtle": "0 1px 3px rgba(0,0,0,0.08)", + "card": "0 4px 8px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.06)", + "modal": "0 20px 25px -5px rgba(0,0,0,0.1), 0 8px 10px -6px rgba(0,0,0,0.06)" + }, + "spacing": { + "unit": "8px", + "scale": { + "xs": "4px", + "sm": "8px", + "md": "16px", + "lg": "24px", + "xl": "32px", + "2xl": "48px" + } + }, + "motion": { + "transition_style": "dissolve", + "animation_speed": "moderate", + "easing": "ease-in-out", + "text_entrance": "fade", + "pacing": "moderate", + "kinetic_typography": false + }, + "logo_placement": { + "preferred_position": "bottom-right", + "min_clear_space": "0.5x", + "min_height": "32px", + "background_contrast": "any" + }, + "colorways": [ + { + "name": "primary", + "foreground": "#FFFFFF", + "background": "#FF6600", + "accent": "#0066CC" + }, + { + "name": "inverted", + "foreground": "#FF6600", + "background": "#FFFFFF", + "accent": "#0066CC", + "border": "#FF6600" + } + ], "type_scale": { "base_width": "1080px", + "heading": { + "font": "primary", + "size": "48px", + "weight": "700", + "line_height": "1.1", + "text_transform": "none" + }, + "subheading": { + "font": "primary", + "size": "24px", + "weight": "600", + "line_height": "1.3" + }, "body": { "font": "secondary", - "line_height": "1.5", "size": "16px", - "weight": "400" + "weight": "400", + "line_height": "1.5" }, "cta": { "font": "primary", - "letter_spacing": "0.05em", "size": "18px", + "weight": "700", "text_transform": "uppercase", - "weight": "700" - }, - "heading": { - "font": "primary", - "line_height": "1.1", - "size": "48px", - "text_transform": "none", - "weight": "700" - }, - "subheading": { - "font": "primary", - "line_height": "1.3", - "size": "24px", - "weight": "600" + "letter_spacing": "0.05em" } + }, + "restrictions": [ + "Never place text over the product", + "Do not use black backgrounds", + "No stock photography of people on phones" + ] + }, + "properties": [ + { + "type": "website", + "identifier": "tide.com", + "primary": true + }, + { + "type": "mobile_app", + "store": "apple", + "identifier": "com.pg.tide" } + ], + "contact": { + "email": "brands@pg.com" } }, { - "colors": { - "primary": "#00A0D2" - }, "id": "pampers", + "url": "https://pampers.com", + "names": [ + { + "en_US": "Pampers" + } + ], + "keller_type": "master", "industries": [ "cpg" ], - "keller_type": "master", "logos": [ { - "orientation": "horizontal", "url": "https://cdn.pg.com/pampers/logo.png", + "orientation": "horizontal", "variant": "primary" } ], - "names": [ - { - "en_US": "Pampers" - } - ], + "colors": { + "primary": "#00A0D2" + }, "properties": [ { + "type": "website", "identifier": "pampers.com", - "primary": true, - "type": "website" + "primary": true } - ], - "url": "https://pampers.com" + ] } ], "contact": { - "email": "brands@pg.com", - "name": "P&G Brand Team" - }, - "house": { - "architecture": "house_of_brands", - "domain": "pg.com", - "name": "Procter & Gamble" + "name": "P&G Brand Team", + "email": "brands@pg.com" }, - "last_updated": "2026-01-15T10:00:00Z", - "version": "1.0" + "last_updated": "2026-01-15T10:00:00Z" }, { - "$schema": "/schemas/3.0.0-rc.3/brand.json", - "authorized_operators": [ - { - "brands": [ - "nike", - "air_jordan" - ], - "countries": [ - "US", - "GB", - "DE", - "FR" - ], - "domain": "wpp.com" - }, - { - "brands": [ - "nike" - ], - "countries": [ - "JP" - ], - "domain": "dentsu.co.jp" - }, - { - "brands": [ - "*" - ], - "domain": "nike.com" - } - ], + "$schema": "/schemas/latest/brand.json", + "version": "1.0", + "house": { + "domain": "nikeinc.com", + "name": "Nike, Inc.", + "architecture": "hybrid" + }, "brands": [ { - "colors": { - "accent": "#FF6600", - "primary": "#111111" - }, "id": "nike", + "url": "https://nike.com", + "names": [ + { + "en_US": "Nike" + }, + { + "zh_CN": "\u8010\u514b" + }, + { + "ja_JP": "\u30ca\u30a4\u30ad" + } + ], "keller_type": "master", "logos": [ { - "background": "dark-bg", - "orientation": "horizontal", "url": "https://cdn.nike.com/swoosh-dark.svg", - "usage": "Swoosh icon for dark backgrounds", - "variant": "icon" + "orientation": "horizontal", + "background": "dark-bg", + "variant": "icon", + "usage": "Swoosh icon for dark backgrounds" }, { - "background": "light-bg", - "orientation": "horizontal", "url": "https://cdn.nike.com/logo-full.svg", - "usage": "Full logo with wordmark for light backgrounds", - "variant": "full-lockup" + "orientation": "horizontal", + "background": "light-bg", + "variant": "full-lockup", + "usage": "Full logo with wordmark for light backgrounds" } ], - "names": [ - { - "en_US": "Nike" - }, - { - "zh_CN": "\u8010\u514b" - }, + "colors": { + "primary": "#111111", + "accent": "#FF6600" + }, + "tone": "inspirational, bold, athletic", + "tagline": [ { - "ja_JP": "\u30ca\u30a4\u30ad" + "en_US": "Just Do It" } ], "properties": [ { + "type": "website", "identifier": "nike.com", - "primary": true, - "type": "website" + "primary": true }, { + "type": "website", "identifier": "nike.cn", - "region": "CN", - "type": "website" + "region": "CN" }, { - "identifier": "com.nike.omega", + "type": "mobile_app", "store": "apple", - "type": "mobile_app" - } - ], - "tagline": [ - { - "en_US": "Just Do It" + "identifier": "com.nike.omega" } - ], - "tone": "inspirational, bold, athletic", - "url": "https://nike.com" + ] }, { - "brand_agent": { - "id": "nike_dam", - "url": "https://dam.nike.com/mcp" - }, - "colors": { - "primary": "#CE1141", - "secondary": "#111111" - }, "id": "air_jordan", - "keller_type": "endorsed", - "logos": [ - { - "background": "transparent-bg", - "orientation": "square", - "url": "https://cdn.nike.com/jumpman.svg", - "variant": "icon" - } - ], + "url": "https://jordan.com", "names": [ { "en_US": "Air Jordan" @@ -1897,202 +2392,143 @@ "en_US": "Jumpman" } ], + "keller_type": "endorsed", "parent_brand": "nike", + "logos": [ + { + "url": "https://cdn.nike.com/jumpman.svg", + "orientation": "square", + "background": "transparent-bg", + "variant": "icon" + } + ], + "colors": { + "primary": "#CE1141", + "secondary": "#111111" + }, "properties": [ { + "type": "website", "identifier": "jordan.com", - "primary": true, - "type": "website" + "primary": true }, { - "identifier": "jumpman23.com", - "type": "website" + "type": "website", + "identifier": "jumpman23.com" } ], - "url": "https://jordan.com" + "brand_agent": { + "url": "https://dam.nike.com/mcp", + "id": "nike_dam" + } }, { "id": "converse", + "url": "https://converse.com", + "names": [ + { + "en_US": "Converse" + } + ], "keller_type": "independent", "logos": [ { - "orientation": "square", "url": "https://cdn.converse.com/star.svg", + "orientation": "square", "variant": "icon" } ], - "names": [ - { - "en_US": "Converse" - } - ], "properties": [ { + "type": "website", "identifier": "converse.com", - "primary": true, - "type": "website" + "primary": true } - ], - "url": "https://converse.com" - } - ], - "house": { - "architecture": "hybrid", - "domain": "nikeinc.com", - "name": "Nike, Inc." - }, - "last_updated": "2026-01-15T10:00:00Z", - "version": "1.0" - } - ], - "oneOf": [ - { - "additionalProperties": false, - "description": "Redirects to a hosted brand.json file at another URL", - "properties": { - "$schema": { - "type": "string" - }, - "authoritative_location": { - "description": "HTTPS URL of the authoritative brand.json file", - "format": "uri", - "pattern": "^https://", - "type": "string" - }, - "last_updated": { - "format": "date-time", - "type": "string" + ] } - }, - "required": [ - "authoritative_location" ], - "title": "Authoritative Location Redirect", - "type": "object" - }, - { - "additionalProperties": false, - "description": "Redirects to the house domain that contains the full brand portfolio", - "properties": { - "$schema": { - "type": "string" - }, - "house": { - "$ref": "#/definitions/domain", - "description": "House domain to fetch brand portfolio from" - }, - "last_updated": { - "format": "date-time", - "type": "string" + "authorized_operators": [ + { + "domain": "wpp.com", + "brands": [ + "nike", + "air_jordan" + ], + "countries": [ + "US", + "GB", + "DE", + "FR" + ] }, - "note": { - "type": "string" + { + "domain": "dentsu.co.jp", + "brands": [ + "nike" + ], + "countries": [ + "JP" + ] }, - "region": { - "description": "ISO 3166-1 alpha-2 country code if this is a regional domain", - "pattern": "^[A-Z]{2}$", - "type": "string" + { + "domain": "nike.com", + "brands": [ + "*" + ] } - }, - "required": [ - "house" ], - "title": "House Redirect", - "type": "object" + "last_updated": "2026-01-15T10:00:00Z" }, { - "additionalProperties": false, - "description": "Brand with an agent that provides brand info via MCP", - "properties": { - "$schema": { - "type": "string" - }, - "brand_agent": { - "$ref": "#/definitions/brand_agent" - }, - "contact": { - "$ref": "#/definitions/contact" - }, - "last_updated": { - "format": "date-time", - "type": "string" - }, - "version": { - "type": "string" - } + "$schema": "/schemas/latest/brand.json", + "version": "1.0", + "house": { + "domain": "mediavine.com", + "name": "Mediavine", + "architecture": "branded_house" }, - "required": [ - "brand_agent" - ], - "title": "Brand Agent", - "type": "object" - }, - { - "additionalProperties": false, - "description": "Full house/brand portfolio with hierarchy, creative assets, and properties", - "properties": { - "$schema": { - "type": "string" - }, - "authorized_operators": { - "description": "Entities authorized to represent brands from this house. Third parties (sellers, platforms) can verify an operator's authorization by checking this list. Operators are identified by domain.", - "items": { - "$ref": "#/definitions/authorized_operator" - }, - "type": "array" - }, - "brands": { - "description": "Brands owned by this house", - "items": { - "$ref": "#/definitions/brand" - }, - "minItems": 1, - "type": "array" - }, - "contact": { - "$ref": "#/definitions/contact" - }, - "house": { - "$ref": "#/definitions/house" - }, - "last_updated": { - "format": "date-time", - "type": "string" - }, - "trademarks": { - "items": { - "additionalProperties": true, - "properties": { - "mark": { - "type": "string" - }, - "number": { - "type": "string" - }, - "registry": { - "type": "string" - } + "brands": [ + { + "id": "mediavine", + "url": "https://mediavine.com", + "names": [ + { + "en_US": "Mediavine" + } + ], + "keller_type": "master", + "properties": [ + { + "type": "website", + "identifier": "mediavine.com", + "primary": true }, - "required": [ - "registry", - "number", - "mark" - ], - "type": "object" - }, - "type": "array" - }, - "version": { - "type": "string" + { + "type": "website", + "identifier": "thehollywoodgossip.com", + "relationship": "delegated" + }, + { + "type": "website", + "identifier": "foodfanatic.com", + "relationship": "delegated" + }, + { + "type": "website", + "identifier": "thebiglead.com", + "relationship": "delegated" + } + ], + "agents": [ + { + "type": "sales", + "url": "https://ads.mediavine.com/mcp", + "id": "mediavine_sales" + } + ] } - }, - "required": [ - "house", - "brands" ], - "title": "House Portfolio", - "type": "object" + "last_updated": "2026-01-15T10:00:00Z" } - ], - "title": "Brand Discovery" + ] } \ No newline at end of file diff --git a/schemas/cache/brand/acquire-rights-request.json b/schemas/cache/brand/acquire-rights-request.json index c58ee48f7..24805599c 100644 --- a/schemas/cache/brand/acquire-rights-request.json +++ b/schemas/cache/brand/acquire-rights-request.json @@ -1,101 +1,109 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Acquire Rights Request", "description": "Binding contractual request to acquire rights from a brand agent. Parallels create_media_buy \u2014 the buyer selects a pricing_option_id from a get_rights response and provides campaign details. The agent clears against existing contracts and returns terms, generation credentials, and disclosure requirements.", + "type": "object", "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "rights_id": { + "type": "string", + "description": "Rights offering identifier from get_rights response" + }, + "pricing_option_id": { + "type": "string", + "description": "Selected pricing option from the rights offering" + }, "buyer": { "$ref": "../core/brand-ref.json", "description": "The buyer's brand identity" }, "campaign": { - "additionalProperties": true, + "type": "object", "description": "Campaign details for rights clearance", "properties": { - "countries": { - "description": "Countries where the campaign will run (ISO 3166-1 alpha-2)", - "items": { - "pattern": "^[A-Z]{2}$", - "type": "string" - }, - "type": "array" - }, "description": { - "description": "Description of how the rights will be used", - "type": "string" + "type": "string", + "description": "Description of how the rights will be used" }, - "end_date": { - "description": "Campaign end date (ISO 8601)", - "format": "date", - "type": "string" + "uses": { + "type": "array", + "description": "Specific rights uses for this campaign", + "items": { + "$ref": "../enums/right-use.json" + }, + "minItems": 1 }, - "estimated_impressions": { - "description": "Estimated total impressions for the campaign", - "minimum": 0, - "type": "integer" + "countries": { + "type": "array", + "description": "Countries where the campaign will run (ISO 3166-1 alpha-2)", + "items": { + "type": "string", + "pattern": "^[A-Z]{2}$" + } }, "format_ids": { + "type": "array", "description": "Creative formats that will be produced", "items": { "$ref": "../core/format-id.json" - }, - "type": "array" + } + }, + "estimated_impressions": { + "type": "integer", + "minimum": 0, + "description": "Estimated total impressions for the campaign" }, "start_date": { - "description": "Campaign start date (ISO 8601)", + "type": "string", "format": "date", - "type": "string" + "description": "Campaign start date (ISO 8601)" }, - "uses": { - "description": "Specific rights uses for this campaign", - "items": { - "$ref": "../enums/right-use.json" - }, - "minItems": 1, - "type": "array" + "end_date": { + "type": "string", + "format": "date", + "description": "Campaign end date (ISO 8601)" } }, "required": [ "description", "uses" ], - "type": "object" + "additionalProperties": true }, - "context": { - "$ref": "../core/context.json" + "revocation_webhook": { + "$ref": "../core/push-notification-config.json", + "description": "Webhook for rights revocation notifications. If the rights holder needs to revoke rights (talent scandal, contract violation, etc.), they POST a revocation-notification to this URL. The buyer is responsible for stopping creative delivery upon receipt." }, - "ext": { - "$ref": "../core/ext.json" + "push_notification_config": { + "$ref": "../core/push-notification-config.json", + "description": "Webhook for async status updates if the acquisition requires approval. The rights agent sends a webhook notification when the status transitions to acquired or rejected." }, "idempotency_key": { + "type": "string", "description": "Client-generated key for safe retries. Resubmitting with the same key returns the original response rather than creating a duplicate acquisition. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.", - "maxLength": 255, "minLength": 16, - "type": "string" - }, - "pricing_option_id": { - "description": "Selected pricing option from the rights offering", - "type": "string" - }, - "push_notification_config": { - "$ref": "../core/push-notification-config.json", - "description": "Webhook for async status updates if the acquisition requires approval. The rights agent sends a webhook notification when the status transitions to acquired or rejected." + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" }, - "revocation_webhook": { - "$ref": "../core/push-notification-config.json", - "description": "Webhook for rights revocation notifications. If the rights holder needs to revoke rights (talent scandal, contract violation, etc.), they POST a revocation-notification to this URL. The buyer is responsible for stopping creative delivery upon receipt." + "context": { + "$ref": "../core/context.json" }, - "rights_id": { - "description": "Rights offering identifier from get_rights response", - "type": "string" + "ext": { + "$ref": "../core/ext.json" } }, "required": [ + "idempotency_key", "rights_id", "pricing_option_id", "buyer", "campaign", "revocation_webhook" ], - "title": "Acquire Rights Request", - "type": "object" + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/brand/acquire-rights-response.json b/schemas/cache/brand/acquire-rights-response.json index fe5bd1cc7..07eb5ff1c 100644 --- a/schemas/cache/brand/acquire-rights-response.json +++ b/schemas/cache/brand/acquire-rights-response.json @@ -1,82 +1,79 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Acquire Rights Response", "description": "Result of a rights acquisition request. Returns one of three statuses: acquired (with terms and generation credentials), pending_approval (requires rights holder review), or rejected (with reason). Uses discriminated union on status field.", + "type": "object", "oneOf": [ { - "additionalProperties": true, - "not": { - "required": [ - "errors" - ] - }, + "title": "AcquireRightsAcquired", "properties": { - "approval_webhook": { - "$ref": "../core/push-notification-config.json", - "description": "Authenticated webhook for submitting creatives for approval. POST a creative-approval-request to the URL using the provided authentication. The response is a creative-approval-response." + "rights_id": { + "type": "string", + "description": "Rights grant identifier" + }, + "status": { + "type": "string", + "const": "acquired", + "description": "Rights have been cleared and credentials issued" }, "brand_id": { - "description": "Brand identifier of the rights subject", - "type": "string" + "type": "string", + "description": "Brand identifier of the rights subject" }, - "context": { - "$ref": "../core/context.json" + "terms": { + "$ref": "rights-terms.json", + "description": "Agreed contractual terms" + }, + "generation_credentials": { + "type": "array", + "description": "Scoped credentials for generating rights-cleared content", + "items": { + "$ref": "../core/generation-credential.json" + } + }, + "restrictions": { + "type": "array", + "description": "Usage restrictions and requirements", + "items": { + "type": "string" + } }, "disclosure": { - "additionalProperties": true, + "type": "object", "description": "Required disclosure for creatives using these rights", "properties": { "required": { - "description": "Whether disclosure is required", - "type": "boolean" + "type": "boolean", + "description": "Whether disclosure is required" }, "text": { - "description": "Disclosure text to include with the creative", - "type": "string" + "type": "string", + "description": "Disclosure text to include with the creative" } }, "required": [ "required" ], - "type": "object" + "additionalProperties": true }, - "ext": { - "$ref": "../core/ext.json" - }, - "generation_credentials": { - "description": "Scoped credentials for generating rights-cleared content", - "items": { - "$ref": "../core/generation-credential.json" - }, - "type": "array" + "approval_webhook": { + "$ref": "../core/push-notification-config.json", + "description": "Authenticated webhook for submitting creatives for approval. POST a creative-approval-request to the URL using the provided authentication. The response is a creative-approval-response." }, - "restrictions": { - "description": "Usage restrictions and requirements", - "items": { - "type": "string" - }, - "type": "array" + "usage_reporting_url": { + "type": "string", + "format": "uri", + "description": "Endpoint for reporting usage against these rights" }, "rights_constraint": { "$ref": "../core/rights-constraint.json", "description": "Pre-built rights constraint for embedding in creative manifests. Populated from the agreed terms \u2014 the buyer does not need to construct it manually." }, - "rights_id": { - "description": "Rights grant identifier", - "type": "string" - }, - "status": { - "const": "acquired", - "description": "Rights have been cleared and credentials issued", - "type": "string" - }, - "terms": { - "$ref": "rights-terms.json", - "description": "Agreed contractual terms" + "context": { + "$ref": "../core/context.json" }, - "usage_reporting_url": { - "description": "Endpoint for reporting usage against these rights", - "format": "uri", - "type": "string" + "ext": { + "$ref": "../core/ext.json" } }, "required": [ @@ -87,40 +84,40 @@ "generation_credentials", "rights_constraint" ], - "title": "AcquireRightsAcquired" - }, - { "additionalProperties": true, "not": { "required": [ "errors" ] - }, + } + }, + { + "title": "AcquireRightsPendingApproval", "properties": { - "brand_id": { + "rights_id": { "type": "string" }, - "context": { - "$ref": "../core/context.json" + "status": { + "type": "string", + "const": "pending_approval", + "description": "Rights require approval from the rights holder" }, - "detail": { - "description": "Explanation of what requires approval", + "brand_id": { "type": "string" }, + "detail": { + "type": "string", + "description": "Explanation of what requires approval" + }, "estimated_response_time": { - "description": "Expected time for approval decision (e.g., '48h', '3 business days')", - "type": "string" + "type": "string", + "description": "Expected time for approval decision (e.g., '48h', '3 business days')" + }, + "context": { + "$ref": "../core/context.json" }, "ext": { "$ref": "../core/ext.json" - }, - "rights_id": { - "type": "string" - }, - "status": { - "const": "pending_approval", - "description": "Rights require approval from the rights holder", - "type": "string" } }, "required": [ @@ -128,43 +125,43 @@ "status", "brand_id" ], - "title": "AcquireRightsPendingApproval" - }, - { "additionalProperties": true, "not": { "required": [ "errors" ] - }, + } + }, + { + "title": "AcquireRightsRejected", "properties": { - "brand_id": { - "type": "string" - }, - "context": { - "$ref": "../core/context.json" - }, - "ext": { - "$ref": "../core/ext.json" - }, - "reason": { - "description": "Why the rights request was rejected. May be sanitized to protect confidential brand rules \u2014 e.g., 'This violates our public figures brand guidelines' rather than naming the specific rule.", - "type": "string" - }, "rights_id": { "type": "string" }, "status": { + "type": "string", "const": "rejected", - "description": "Rights request was rejected", + "description": "Rights request was rejected" + }, + "brand_id": { "type": "string" }, + "reason": { + "type": "string", + "description": "Why the rights request was rejected. May be sanitized to protect confidential brand rules \u2014 e.g., 'This violates our public figures brand guidelines' rather than naming the specific rule." + }, "suggestions": { + "type": "array", "description": "Actionable alternatives the buyer can try. If present, the rejection is fixable \u2014 the buyer can adjust their request. If absent, the rejection is final for this talent/rights combination.", "items": { "type": "string" - }, - "type": "array" + } + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" } }, "required": [ @@ -173,29 +170,25 @@ "brand_id", "reason" ], - "title": "AcquireRightsRejected" - }, - { "additionalProperties": true, "not": { - "anyOf": [ - { - "required": [ - "status" - ] - } + "required": [ + "errors" ] - }, + } + }, + { + "title": "AcquireRightsError", "properties": { - "context": { - "$ref": "../core/context.json" - }, "errors": { + "type": "array", "items": { "$ref": "../core/error.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" }, "ext": { "$ref": "../core/ext.json" @@ -204,9 +197,16 @@ "required": [ "errors" ], - "title": "AcquireRightsError" + "additionalProperties": true, + "not": { + "anyOf": [ + { + "required": [ + "status" + ] + } + ] + } } - ], - "title": "Acquire Rights Response", - "type": "object" + ] } \ No newline at end of file diff --git a/schemas/cache/brand/creative-approval-request.json b/schemas/cache/brand/creative-approval-request.json new file mode 100644 index 000000000..cf2eaf43d --- /dev/null +++ b/schemas/cache/brand/creative-approval-request.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Creative Approval Request", + "description": "Payload submitted by the buyer to the approval_webhook URL from acquire_rights. Contains the creative for rights holder review before distribution.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "rights_id": { + "type": "string", + "description": "Rights grant this creative was produced under" + }, + "creative_id": { + "type": "string", + "description": "Buyer-assigned creative identifier. Equivalent to OpenRTB crid. Used to track approval status across resubmissions." + }, + "creative_url": { + "type": "string", + "format": "uri", + "description": "URL where the creative asset can be retrieved for review" + }, + "creative_format": { + "$ref": "../core/format-id.json", + "description": "Format of the creative being submitted" + }, + "description": { + "type": "string", + "description": "Description of the creative for reviewer context" + }, + "metadata": { + "type": "object", + "description": "Additional creative metadata (duration, dimensions, target audience, etc.)", + "additionalProperties": true + }, + "idempotency_key": { + "type": "string", + "description": "Client-generated key for safe retries. Resubmitting with the same key returns the original response. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.", + "minLength": 16, + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "idempotency_key", + "rights_id", + "creative_url" + ], + "additionalProperties": true +} \ No newline at end of file diff --git a/schemas/cache/brand/creative-approval-response.json b/schemas/cache/brand/creative-approval-response.json new file mode 100644 index 000000000..18cf23137 --- /dev/null +++ b/schemas/cache/brand/creative-approval-response.json @@ -0,0 +1,182 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Creative Approval Response", + "description": "Response from the approval_webhook after reviewing a submitted creative. Uses discriminated union on status field: approved, rejected, or pending_review.", + "type": "object", + "oneOf": [ + { + "title": "CreativeApproved", + "properties": { + "status": { + "type": "string", + "const": "approved", + "description": "Creative has been approved for distribution" + }, + "rights_id": { + "type": "string" + }, + "creative_id": { + "type": "string", + "description": "Echo of the buyer's creative identifier" + }, + "creative_url": { + "type": "string", + "format": "uri" + }, + "approved_at": { + "type": "string", + "format": "date-time" + }, + "conditions": { + "type": "array", + "description": "Conditions on the approval (e.g., 'approved for NL market only')", + "items": { + "type": "string" + } + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "status", + "rights_id" + ], + "additionalProperties": true, + "not": { + "required": [ + "errors" + ] + } + }, + { + "title": "CreativeRejected", + "properties": { + "status": { + "type": "string", + "const": "rejected", + "description": "Creative was rejected" + }, + "rights_id": { + "type": "string" + }, + "creative_id": { + "type": "string", + "description": "Echo of the buyer's creative identifier" + }, + "creative_url": { + "type": "string", + "format": "uri" + }, + "reason": { + "type": "string", + "description": "Why the creative was rejected" + }, + "suggestions": { + "type": "array", + "description": "Actionable feedback for revision. If present, the buyer can revise and resubmit the creative. If absent, the rejection is final for this creative concept.", + "items": { + "type": "string" + } + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "status", + "rights_id", + "reason" + ], + "additionalProperties": true, + "not": { + "required": [ + "errors" + ] + } + }, + { + "title": "CreativePendingReview", + "properties": { + "status": { + "type": "string", + "const": "pending_review", + "description": "Creative is queued for review" + }, + "rights_id": { + "type": "string" + }, + "creative_id": { + "type": "string", + "description": "Echo of the buyer's creative identifier" + }, + "creative_url": { + "type": "string", + "format": "uri" + }, + "estimated_response_time": { + "type": "string", + "description": "Expected time for review (e.g., '24h', '2 business days')" + }, + "status_url": { + "type": "string", + "format": "uri", + "description": "URL to poll for updated approval status. GET this URL to receive a creative-approval-response. Poll at reasonable intervals (suggested: every 5 minutes, back off after 1 hour to every 30 minutes). Stop polling after estimated_response_time has elapsed and the status is still pending_review." + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "status", + "rights_id" + ], + "additionalProperties": true, + "not": { + "required": [ + "errors" + ] + } + }, + { + "title": "CreativeApprovalError", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "../core/error.json" + }, + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "errors" + ], + "additionalProperties": true, + "not": { + "anyOf": [ + { + "required": [ + "status" + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/schemas/cache/brand/get-brand-identity-request.json b/schemas/cache/brand/get-brand-identity-request.json index 6ada8f377..554e5bebd 100644 --- a/schemas/cache/brand/get-brand-identity-request.json +++ b/schemas/cache/brand/get-brand-identity-request.json @@ -1,21 +1,25 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Get Brand Identity Request", "description": "Request brand identity data from a brand agent. Core identity (house, names, description, logos) is always public. Linked accounts get deeper data: high-res assets, voice configs, tone guidelines, and rights availability.", + "type": "object", "properties": { - "brand_id": { - "description": "Brand identifier from brand.json brands array", - "type": "string" - }, - "context": { - "$ref": "../core/context.json" + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 }, - "ext": { - "$ref": "../core/ext.json" + "brand_id": { + "type": "string", + "description": "Brand identifier from brand.json brands array" }, "fields": { + "type": "array", "description": "Optional identity sections to include in the response. When omitted, all sections the caller is authorized to see are returned. Core fields (brand_id, house, names) are always returned and do not need to be requested.", + "minItems": 1, "items": { + "type": "string", "enum": [ "description", "industries", @@ -29,20 +33,22 @@ "voice_synthesis", "assets", "rights" - ], - "type": "string" - }, - "minItems": 1, - "type": "array" + ] + } }, "use_case": { - "description": "Intended use case, so the agent can tailor the response. A 'voice_synthesis' use case returns voice configs; a 'likeness' use case returns high-res photos and appearance guidelines.", - "type": "string" + "type": "string", + "description": "Intended use case, so the agent can tailor the response. A 'voice_synthesis' use case returns voice configs; a 'likeness' use case returns high-res photos and appearance guidelines." + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" } }, "required": [ "brand_id" ], - "title": "Get Brand Identity Request", - "type": "object" + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/brand/get-brand-identity-response.json b/schemas/cache/brand/get-brand-identity-response.json index 0ab4a0a1b..160a6ccf9 100644 --- a/schemas/cache/brand/get-brand-identity-response.json +++ b/schemas/cache/brand/get-brand-identity-response.json @@ -1,452 +1,529 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Brand Identity Response", "description": "Brand identity data from a brand agent. Core identity (house, names, description, logos) is always public. Authorized callers receive richer data (high-res assets, voice synthesis, tone guidelines, rights availability). Includes available_fields to signal what the caller could unlock by linking their account.", + "type": "object", "oneOf": [ { - "additionalProperties": true, - "not": { - "required": [ - "errors" - ] - }, + "title": "GetBrandIdentitySuccess", "properties": { - "assets": { - "description": "Available brand assets (images, audio, video). Authorized callers only. Shape matches brand.json asset definition.", + "brand_id": { + "type": "string", + "description": "Brand identifier" + }, + "house": { + "type": "object", + "description": "The house (corporate entity) this brand belongs to. Always returned regardless of authorization level.", + "properties": { + "domain": { + "type": "string", + "description": "House domain (e.g., nikeinc.com)" + }, + "name": { + "type": "string", + "description": "House display name" + } + }, + "required": [ + "domain", + "name" + ], + "additionalProperties": true + }, + "names": { + "type": "array", + "description": "Localized brand names with BCP 47 locale code keys (e.g., 'en_US', 'fr_CA'). Bare language codes ('en') are accepted as wildcards for backwards compatibility.", "items": { - "additionalProperties": true, + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "string" + } + } + }, + "description": { + "type": "string", + "description": "Brand description" + }, + "industries": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "Brand industries." + }, + "keller_type": { + "type": "string", + "enum": [ + "master", + "sub_brand", + "endorsed", + "independent" + ], + "description": "Brand architecture type: master (primary brand of house), sub_brand (carries parent name), endorsed (independent identity backed by parent), independent (operates separately)" + }, + "logos": { + "type": "array", + "description": "Brand logos. Public callers get standard logos; authorized callers also receive high-res variants. Shape matches brand.json logo definition.", + "items": { + "type": "object", "properties": { - "asset_id": { - "description": "Unique identifier", - "type": "string" - }, - "asset_type": { - "$ref": "../enums/asset-content-type.json", - "description": "Type of asset content" - }, - "description": { - "description": "Asset description or usage notes", - "type": "string" - }, - "duration_seconds": { - "description": "Video/audio duration in seconds", - "type": "number" - }, - "file_size_bytes": { - "description": "File size in bytes", - "type": "integer" + "url": { + "type": "string", + "format": "uri", + "description": "URL to the logo asset" }, - "format": { - "description": "File format (e.g., 'jpg', 'mp4')", - "type": "string" + "orientation": { + "type": "string", + "enum": [ + "square", + "horizontal", + "vertical", + "stacked" + ], + "description": "Logo aspect ratio orientation" }, - "height": { - "description": "Image/video height in pixels", - "type": "integer" + "background": { + "type": "string", + "enum": [ + "dark-bg", + "light-bg", + "transparent-bg" + ], + "description": "Background compatibility" }, - "name": { - "description": "Human-readable name", - "type": "string" + "variant": { + "type": "string", + "enum": [ + "primary", + "secondary", + "icon", + "wordmark", + "full-lockup" + ], + "description": "Logo variant type" }, "tags": { - "description": "Tags for discovery", + "type": "array", "items": { "type": "string" }, - "type": "array" + "description": "Additional semantic tags" }, - "url": { - "description": "URL to CDN-hosted asset file", - "format": "uri", - "type": "string" + "usage": { + "type": "string", + "description": "When to use this logo variant" }, "width": { - "description": "Image/video width in pixels", - "type": "integer" + "type": "integer", + "description": "Width in pixels" + }, + "height": { + "type": "integer", + "description": "Height in pixels" } }, "required": [ - "asset_id", - "asset_type", "url" ], - "type": "object" - }, - "type": "array" - }, - "available_fields": { - "description": "Fields available but not returned in this response due to authorization level. Tells the caller what they would gain by linking their account via sync_accounts. Values match the request fields enum.", - "items": { - "enum": [ - "description", - "industries", - "keller_type", - "logos", - "colors", - "fonts", - "visual_guidelines", - "tone", - "tagline", - "voice_synthesis", - "assets", - "rights" - ], - "type": "string" - }, - "type": "array" - }, - "brand_id": { - "description": "Brand identifier", - "type": "string" + "additionalProperties": true + } }, "colors": { - "additionalProperties": true, + "type": "object", "description": "Brand color palette. Each role accepts a single hex color or an array of hex colors. Shape matches brand.json colors definition.", "properties": { - "accent": { + "primary": { "oneOf": [ { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, { + "type": "array", "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, - "minItems": 1, - "type": "array" + "minItems": 1 } ] }, - "background": { + "secondary": { "oneOf": [ { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, { + "type": "array", "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, - "minItems": 1, - "type": "array" + "minItems": 1 } ] }, - "primary": { + "accent": { "oneOf": [ { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, { + "type": "array", "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, - "minItems": 1, - "type": "array" + "minItems": 1 } ] }, - "secondary": { + "background": { "oneOf": [ { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, { + "type": "array", "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, - "minItems": 1, - "type": "array" + "minItems": 1 } ] }, "text": { "oneOf": [ { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, { + "type": "array", "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" }, - "minItems": 1, - "type": "array" + "minItems": 1 } ] } }, - "type": "object" - }, - "context": { - "$ref": "../core/context.json" - }, - "description": { - "description": "Brand description", - "type": "string" - }, - "ext": { - "$ref": "../core/ext.json" + "additionalProperties": true }, "fonts": { + "type": "object", + "description": "Brand typography. Each key is a role name (e.g., 'primary', 'secondary') referenced by type_scale entries. Values are either a CSS font-family string or a structured object with family name and font files. Shape matches brand.json fonts definition.", + "maxProperties": 20, + "definitions": { + "font_role": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "family": { + "type": "string", + "description": "CSS font-family name" + }, + "files": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "HTTPS URL to the font file" + }, + "weight": { + "type": "integer", + "minimum": 100, + "maximum": 900, + "description": "CSS numeric font-weight" + }, + "weight_range": { + "type": "array", + "items": { + "type": "integer", + "minimum": 100, + "maximum": 900 + }, + "minItems": 2, + "maxItems": 2, + "description": "Variable font weight axis range as [min, max]" + }, + "style": { + "type": "string", + "enum": [ + "normal", + "italic", + "oblique" + ], + "description": "CSS font-style" + } + }, + "required": [ + "url" + ], + "additionalProperties": true + }, + "maxItems": 36 + }, + "opentype_features": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-z0-9]{4}$" + }, + "maxItems": 20, + "description": "OpenType feature tags to enable (e.g., ['ss01', 'tnum'])" + }, + "fallbacks": { + "type": "array", + "items": { + "type": "string", + "maxLength": 100 + }, + "maxItems": 10, + "description": "Ordered fallback font-family names for script coverage" + } + }, + "required": [ + "family" + ], + "additionalProperties": true + } + ] + } + }, + "properties": { + "primary": { + "$ref": "#/oneOf/0/properties/fonts/definitions/font_role", + "description": "Primary font family" + }, + "secondary": { + "$ref": "#/oneOf/0/properties/fonts/definitions/font_role", + "description": "Secondary font family" + } + }, + "additionalProperties": { + "$ref": "#/oneOf/0/properties/fonts/definitions/font_role" + } + }, + "visual_guidelines": { + "type": "object", "additionalProperties": true, - "description": "Brand typography. Shape matches brand.json fonts definition.", + "description": "Structured visual rules for generative creative systems (photography, graphic_style, colorways, type_scale, motion). Matches brand.json visual_guidelines definition. Authorized callers only." + }, + "tone": { + "type": "object", + "description": "Brand voice and messaging guidelines", "properties": { - "font_urls": { - "description": "URLs to web font files", + "voice": { + "type": "string", + "description": "Brand personality described as comma-separated adjectives (e.g., 'enthusiastic, warm, competitive')" + }, + "attributes": { + "type": "array", "items": { - "format": "uri", "type": "string" }, - "type": "array" + "description": "Personality traits that characterize the brand voice, used as prompt guidance" }, - "primary": { - "description": "Primary font family", - "type": "string" + "dos": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Approved messaging approaches, content themes, and reference points" }, - "secondary": { - "description": "Secondary font family", - "type": "string" + "donts": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Prohibited topics, competitor references, and phrasings to avoid" } }, - "type": "object" + "additionalProperties": true }, - "house": { - "additionalProperties": true, - "description": "The house (corporate entity) this brand belongs to. Always returned regardless of authorization level.", + "tagline": { + "oneOf": [ + { + "type": "string", + "description": "Plain tagline string for backwards compatibility" + }, + { + "type": "array", + "description": "Localized taglines with BCP 47 locale codes", + "items": { + "type": "object", + "minProperties": 1, + "maxProperties": 1, + "additionalProperties": { + "type": "string", + "minLength": 1 + } + }, + "minItems": 1 + } + ], + "description": "Brand tagline or slogan. Accepts a plain string or a localized array matching the names pattern." + }, + "voice_synthesis": { + "type": "object", + "description": "Voice synthesis configuration for AI-generated audio", "properties": { - "domain": { - "description": "House domain (e.g., nikeinc.com)", + "provider": { "type": "string" }, - "name": { - "description": "House display name", + "voice_id": { "type": "string" + }, + "settings": { + "type": "object", + "additionalProperties": true } }, - "required": [ - "domain", - "name" - ], - "type": "object" - }, - "industries": { - "description": "Brand industries.", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" + "additionalProperties": true }, - "keller_type": { - "description": "Brand architecture type: master (primary brand of house), sub_brand (carries parent name), endorsed (independent identity backed by parent), independent (operates separately)", - "enum": [ - "master", - "sub_brand", - "endorsed", - "independent" - ], - "type": "string" - }, - "logos": { - "description": "Brand logos. Public callers get standard logos; authorized callers also receive high-res variants. Shape matches brand.json logo definition.", + "assets": { + "type": "array", + "description": "Available brand assets (images, audio, video). Authorized callers only. Shape matches brand.json asset definition.", "items": { - "additionalProperties": true, + "type": "object", "properties": { - "background": { - "description": "Background compatibility", - "enum": [ - "dark-bg", - "light-bg", - "transparent-bg" - ], - "type": "string" + "asset_id": { + "type": "string", + "description": "Unique identifier" }, - "height": { - "description": "Height in pixels", - "type": "integer" + "asset_type": { + "$ref": "../enums/asset-content-type.json", + "description": "Type of asset content" }, - "orientation": { - "description": "Logo aspect ratio orientation", - "enum": [ - "square", - "horizontal", - "vertical", - "stacked" - ], - "type": "string" + "url": { + "type": "string", + "format": "uri", + "description": "URL to CDN-hosted asset file" }, "tags": { - "description": "Additional semantic tags", + "type": "array", "items": { "type": "string" }, - "type": "array" + "description": "Tags for discovery" }, - "url": { - "description": "URL to the logo asset", - "format": "uri", - "type": "string" - }, - "usage": { - "description": "When to use this logo variant", - "type": "string" + "name": { + "type": "string", + "description": "Human-readable name" }, - "variant": { - "description": "Logo variant type", - "enum": [ - "primary", - "secondary", - "icon", - "wordmark", - "full-lockup" - ], - "type": "string" + "description": { + "type": "string", + "description": "Asset description or usage notes" }, "width": { - "description": "Width in pixels", - "type": "integer" + "type": "integer", + "description": "Image/video width in pixels" + }, + "height": { + "type": "integer", + "description": "Image/video height in pixels" + }, + "duration_seconds": { + "type": "number", + "description": "Video/audio duration in seconds" + }, + "file_size_bytes": { + "type": "integer", + "description": "File size in bytes" + }, + "format": { + "type": "string", + "description": "File format (e.g., 'jpg', 'mp4')" } }, "required": [ + "asset_id", + "asset_type", "url" ], - "type": "object" - }, - "type": "array" - }, - "names": { - "description": "Localized brand names with BCP 47 locale code keys (e.g., 'en_US', 'fr_CA'). Bare language codes ('en') are accepted as wildcards for backwards compatibility.", - "items": { - "additionalProperties": { - "type": "string" - }, - "minProperties": 1, - "type": "object" - }, - "type": "array" + "additionalProperties": true + } }, "rights": { - "additionalProperties": true, + "type": "object", "description": "Rights availability summary. For detailed pricing, use get_rights.", "properties": { "available_uses": { + "type": "array", "items": { "$ref": "../enums/right-use.json" - }, - "type": "array" - }, - "content_restrictions": { - "items": { - "type": "string" - }, - "type": "array" + } }, "countries": { + "type": "array", "description": "Countries where rights are available (ISO 3166-1 alpha-2). If omitted, rights are available worldwide.", "items": { - "pattern": "^[A-Z]{2}$", - "type": "string" - }, - "type": "array" + "type": "string", + "pattern": "^[A-Z]{2}$" + } }, "excluded_countries": { + "type": "array", "description": "Countries excluded from availability (ISO 3166-1 alpha-2)", "items": { - "pattern": "^[A-Z]{2}$", - "type": "string" - }, - "type": "array" + "type": "string", + "pattern": "^[A-Z]{2}$" + } }, "exclusivity_model": { "type": "string" - } - }, - "type": "object" - }, - "tagline": { - "description": "Brand tagline or slogan. Accepts a plain string or a localized array matching the names pattern.", - "oneOf": [ - { - "description": "Plain tagline string for backwards compatibility", - "type": "string" }, - { - "description": "Localized taglines with BCP 47 locale codes", - "items": { - "additionalProperties": { - "minLength": 1, - "type": "string" - }, - "maxProperties": 1, - "minProperties": 1, - "type": "object" - }, - "minItems": 1, - "type": "array" - } - ] - }, - "tone": { - "additionalProperties": true, - "description": "Brand voice and messaging guidelines", - "properties": { - "attributes": { - "description": "Personality traits that characterize the brand voice, used as prompt guidance", - "items": { - "type": "string" - }, - "type": "array" - }, - "donts": { - "description": "Prohibited topics, competitor references, and phrasings to avoid", - "items": { - "type": "string" - }, - "type": "array" - }, - "dos": { - "description": "Approved messaging approaches, content themes, and reference points", + "content_restrictions": { + "type": "array", "items": { "type": "string" - }, - "type": "array" - }, - "voice": { - "description": "Brand personality described as comma-separated adjectives (e.g., 'enthusiastic, warm, competitive')", - "type": "string" + } } }, - "type": "object" + "additionalProperties": true }, - "visual_guidelines": { - "additionalProperties": true, - "description": "Structured visual rules for generative creative systems (photography, graphic_style, colorways, type_scale, motion). Matches brand.json visual_guidelines definition. Authorized callers only.", - "type": "object" + "available_fields": { + "type": "array", + "description": "Fields available but not returned in this response due to authorization level. Tells the caller what they would gain by linking their account via sync_accounts. Values match the request fields enum.", + "items": { + "type": "string", + "enum": [ + "description", + "industries", + "keller_type", + "logos", + "colors", + "fonts", + "visual_guidelines", + "tone", + "tagline", + "voice_synthesis", + "assets", + "rights" + ] + } }, - "voice_synthesis": { - "additionalProperties": true, - "description": "Voice synthesis configuration for AI-generated audio", - "properties": { - "provider": { - "type": "string" - }, - "settings": { - "additionalProperties": true, - "type": "object" - }, - "voice_id": { - "type": "string" - } - }, - "type": "object" + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" } }, "required": [ @@ -454,9 +531,33 @@ "house", "names" ], - "title": "GetBrandIdentitySuccess" + "additionalProperties": true, + "not": { + "required": [ + "errors" + ] + } }, { + "title": "GetBrandIdentityError", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "../core/error.json" + }, + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "errors" + ], "additionalProperties": true, "not": { "anyOf": [ @@ -476,28 +577,7 @@ ] } ] - }, - "properties": { - "context": { - "$ref": "../core/context.json" - }, - "errors": { - "items": { - "$ref": "../core/error.json" - }, - "minItems": 1, - "type": "array" - }, - "ext": { - "$ref": "../core/ext.json" - } - }, - "required": [ - "errors" - ], - "title": "GetBrandIdentityError" + } } - ], - "title": "Get Brand Identity Response", - "type": "object" + ] } \ No newline at end of file diff --git a/schemas/cache/brand/get-rights-request.json b/schemas/cache/brand/get-rights-request.json index 967dc7432..d2766409c 100644 --- a/schemas/cache/brand/get-rights-request.json +++ b/schemas/cache/brand/get-rights-request.json @@ -1,61 +1,67 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Get Rights Request", "description": "Search for licensable rights across a brand agent's roster. Returns matches with pricing. Discovery is natural-language-first \u2014 no taxonomy for categories. The agent interprets intent from the query and filters based on the buyer's brand compatibility.", + "type": "object", "properties": { - "brand_id": { - "description": "Search within a specific brand's rights. If omitted, searches across the agent's full roster.", - "type": "string" + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "query": { + "type": "string", + "description": "Natural language description of desired rights. The agent interprets intent, budget signals, and compatibility from this text.", + "maxLength": 2000 + }, + "uses": { + "type": "array", + "description": "Rights uses being requested. The agent returns options covering these uses, potentially bundled into composite pricing.", + "items": { + "$ref": "../enums/right-use.json" + }, + "minItems": 1 }, "buyer_brand": { "$ref": "../core/brand-ref.json", "description": "The buyer's brand. The agent fetches the buyer's brand.json for compatibility filtering (e.g., dietary conflicts, competitor exclusions)." }, - "context": { - "$ref": "../core/context.json" - }, "countries": { + "type": "array", "description": "Countries where rights are needed (ISO 3166-1 alpha-2). Filters to rights available in these markets.", "items": { - "pattern": "^[A-Z]{2}$", - "type": "string" - }, - "type": "array" + "type": "string", + "pattern": "^[A-Z]{2}$" + } }, - "ext": { - "$ref": "../core/ext.json" + "brand_id": { + "type": "string", + "description": "Search within a specific brand's rights. If omitted, searches across the agent's full roster." + }, + "right_type": { + "$ref": "../enums/right-type.json", + "description": "Filter by type of rights (talent, music, stock_media, etc.)" }, "include_excluded": { - "default": false, + "type": "boolean", "description": "Include filtered-out results in the excluded array with reasons. Defaults to false.", - "type": "boolean" + "default": false }, "pagination": { "$ref": "../core/pagination-request.json", "description": "Pagination parameters for large result sets" }, - "query": { - "description": "Natural language description of desired rights. The agent interprets intent, budget signals, and compatibility from this text.", - "maxLength": 2000, - "type": "string" - }, - "right_type": { - "$ref": "../enums/right-type.json", - "description": "Filter by type of rights (talent, music, stock_media, etc.)" + "context": { + "$ref": "../core/context.json" }, - "uses": { - "description": "Rights uses being requested. The agent returns options covering these uses, potentially bundled into composite pricing.", - "items": { - "$ref": "../enums/right-use.json" - }, - "minItems": 1, - "type": "array" + "ext": { + "$ref": "../core/ext.json" } }, "required": [ "query", "uses" ], - "title": "Get Rights Request", - "type": "object" + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/brand/get-rights-response.json b/schemas/cache/brand/get-rights-response.json index fcc3d13d0..f402b02f6 100644 --- a/schemas/cache/brand/get-rights-response.json +++ b/schemas/cache/brand/get-rights-response.json @@ -1,138 +1,115 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Rights Response", "description": "Licensable rights matching the search criteria, with pricing options. Each result is a complete snapshot of current availability (stateless, DDEX PIE pattern). Excluded results explain why they were filtered out.", + "type": "object", "oneOf": [ { - "additionalProperties": true, - "not": { - "required": [ - "errors" - ] - }, + "title": "GetRightsSuccess", "properties": { - "context": { - "$ref": "../core/context.json" - }, - "excluded": { - "description": "Results that matched but were filtered out, with reasons", + "rights": { + "type": "array", + "description": "Matching rights with pricing options, ranked by relevance", "items": { - "additionalProperties": true, + "type": "object", "properties": { + "rights_id": { + "type": "string", + "description": "Identifier for this rights offering. Referenced in acquire_rights." + }, "brand_id": { - "type": "string" + "type": "string", + "description": "Brand identifier from the agent's roster" }, "name": { - "type": "string" + "type": "string", + "description": "Display name of the rights subject" }, - "reason": { - "description": "Why this result was excluded. May be sanitized to protect confidential brand rules.", - "type": "string" + "description": { + "type": "string", + "description": "Description of the rights subject" }, - "suggestions": { - "description": "Actionable alternatives if the exclusion is fixable (e.g., 'Available in BE and DE markets'). Absent if the exclusion is final.", + "right_type": { + "$ref": "../enums/right-type.json" + }, + "match_score": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Relevance score from 0 to 1" + }, + "match_reasons": { + "type": "array", + "description": "Human-readable reasons for the match", "items": { "type": "string" - }, - "type": "array" - } - }, - "required": [ - "brand_id", - "reason" - ], - "type": "object" - }, - "type": "array" - }, - "ext": { - "$ref": "../core/ext.json" - }, - "rights": { - "description": "Matching rights with pricing options, ranked by relevance", - "items": { - "additionalProperties": true, - "properties": { + } + }, "available_uses": { + "type": "array", "description": "Rights uses available for licensing", "items": { "$ref": "../enums/right-use.json" - }, - "type": "array" - }, - "brand_id": { - "description": "Brand identifier from the agent's roster", - "type": "string" - }, - "content_restrictions": { - "description": "Content restrictions or approval requirements", - "items": { - "type": "string" - }, - "type": "array" + } }, "countries": { + "type": "array", "description": "Countries where rights are available (ISO 3166-1 alpha-2). When both countries and excluded_countries are present, the effective set is countries minus excluded_countries. If neither is present, all countries are available.", "items": { - "pattern": "^[A-Z]{2}$", - "type": "string" - }, - "type": "array" - }, - "description": { - "description": "Description of the rights subject", - "type": "string" + "type": "string", + "pattern": "^[A-Z]{2}$" + } }, "excluded_countries": { + "type": "array", "description": "Countries excluded from availability", "items": { - "pattern": "^[A-Z]{2}$", - "type": "string" - }, - "type": "array" + "type": "string", + "pattern": "^[A-Z]{2}$" + } }, "exclusivity_status": { - "additionalProperties": true, + "type": "object", "description": "Current exclusivity availability", "properties": { "available": { - "description": "Whether exclusivity is available", - "type": "boolean" + "type": "boolean", + "description": "Whether exclusivity is available" }, "existing_exclusives": { + "type": "array", "description": "Active exclusivity commitments that may affect availability. Implementers should use vague descriptions ('exclusive commitment in this category') rather than specific deal terms to protect confidential business relationships.", "items": { "type": "string" - }, - "type": "array" + } } }, - "type": "object" + "additionalProperties": true }, - "match_reasons": { - "description": "Human-readable reasons for the match", + "pricing_options": { + "type": "array", + "description": "Available pricing options for these rights", "items": { - "type": "string" + "$ref": "rights-pricing-option.json" }, - "type": "array" - }, - "match_score": { - "description": "Relevance score from 0 to 1", - "maximum": 1, - "minimum": 0, - "type": "number" + "minItems": 1 }, - "name": { - "description": "Display name of the rights subject", - "type": "string" + "content_restrictions": { + "type": "array", + "description": "Content restrictions or approval requirements", + "items": { + "type": "string" + } }, "preview_assets": { + "type": "array", "description": "Preview-only assets for evaluation", "items": { - "additionalProperties": true, + "type": "object", "properties": { "url": { - "format": "uri", - "type": "string" + "type": "string", + "format": "uri" }, "usage": { "type": "string" @@ -141,24 +118,8 @@ "required": [ "url" ], - "type": "object" - }, - "type": "array" - }, - "pricing_options": { - "description": "Available pricing options for these rights", - "items": { - "$ref": "rights-pricing-option.json" - }, - "minItems": 1, - "type": "array" - }, - "right_type": { - "$ref": "../enums/right-type.json" - }, - "rights_id": { - "description": "Identifier for this rights offering. Referenced in acquire_rights.", - "type": "string" + "additionalProperties": true + } } }, "required": [ @@ -168,37 +129,69 @@ "available_uses", "pricing_options" ], - "type": "object" - }, - "type": "array" + "additionalProperties": true + } + }, + "excluded": { + "type": "array", + "description": "Results that matched but were filtered out, with reasons", + "items": { + "type": "object", + "properties": { + "brand_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "reason": { + "type": "string", + "description": "Why this result was excluded. May be sanitized to protect confidential brand rules." + }, + "suggestions": { + "type": "array", + "description": "Actionable alternatives if the exclusion is fixable (e.g., 'Available in BE and DE markets'). Absent if the exclusion is final.", + "items": { + "type": "string" + } + } + }, + "required": [ + "brand_id", + "reason" + ], + "additionalProperties": true + } + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" } }, "required": [ "rights" ], - "title": "GetRightsSuccess" - }, - { "additionalProperties": true, "not": { - "anyOf": [ - { - "required": [ - "rights" - ] - } + "required": [ + "errors" ] - }, + } + }, + { + "title": "GetRightsError", "properties": { - "context": { - "$ref": "../core/context.json" - }, "errors": { + "type": "array", "items": { "$ref": "../core/error.json" }, - "minItems": 1, - "type": "array" + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" }, "ext": { "$ref": "../core/ext.json" @@ -207,9 +200,16 @@ "required": [ "errors" ], - "title": "GetRightsError" + "additionalProperties": true, + "not": { + "anyOf": [ + { + "required": [ + "rights" + ] + } + ] + } } - ], - "title": "Get Rights Response", - "type": "object" + ] } \ No newline at end of file diff --git a/schemas/cache/brand/revocation-notification.json b/schemas/cache/brand/revocation-notification.json new file mode 100644 index 000000000..9bb1fbde0 --- /dev/null +++ b/schemas/cache/brand/revocation-notification.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Revocation Notification", + "description": "Payload sent by a rights holder to a buyer's revocation_webhook when rights are revoked. The buyer must cease creative delivery by effective_at. Partial revocation is supported \u2014 if revoked_uses is present, only those uses are revoked.", + "type": "object", + "properties": { + "notification_id": { + "type": "string", + "description": "Unique identifier for this notification. Buyers use this for deduplication \u2014 the same revocation may be delivered multiple times." + }, + "rights_id": { + "type": "string", + "description": "The revoked rights grant identifier" + }, + "brand_id": { + "type": "string", + "description": "Brand identifier of the rights subject" + }, + "reason": { + "type": "string", + "description": "Human-readable reason for revocation" + }, + "effective_at": { + "type": "string", + "format": "date-time", + "description": "When the revocation takes effect. Immediate revocations use current time. Grace periods use a future time. The buyer must stop serving creative using these rights by this time." + }, + "revoked_uses": { + "type": "array", + "description": "If present, only these uses are revoked (partial revocation). If absent, all uses under the grant are revoked.", + "items": { + "$ref": "../enums/right-use.json" + }, + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "notification_id", + "rights_id", + "brand_id", + "reason", + "effective_at" + ], + "additionalProperties": true +} \ No newline at end of file diff --git a/schemas/cache/brand/rights-pricing-option.json b/schemas/cache/brand/rights-pricing-option.json index a46f964b5..0a251b18b 100644 --- a/schemas/cache/brand/rights-pricing-option.json +++ b/schemas/cache/brand/rights-pricing-option.json @@ -1,36 +1,37 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Rights Pricing Option", "description": "A pricing option for licensable rights. Separate from media-buy pricing options \u2014 rights pricing includes period, impression caps, overage rates, and use-type scoping.", + "type": "object", "properties": { - "currency": { - "description": "ISO 4217 currency code", - "pattern": "^[A-Z]{3}$", - "type": "string" - }, - "description": { - "description": "Human-readable description of this pricing option", - "type": "string" - }, - "ext": { - "$ref": "../core/ext.json" - }, - "impression_cap": { - "description": "Maximum impressions included in this pricing option per period", - "minimum": 1, - "type": "integer" + "pricing_option_id": { + "type": "string", + "description": "Unique identifier for this pricing option. Referenced in acquire_rights and report_usage." }, "model": { "$ref": "../enums/pricing-model.json", "description": "Pricing model (cpm, flat_rate, etc.)" }, - "overage_cpm": { - "description": "CPM rate applied to impressions exceeding the impression_cap", + "price": { + "type": "number", "minimum": 0, - "type": "number" + "description": "Price amount. Interpretation depends on model: CPM = cost per 1,000 impressions, flat_rate = fixed cost per period." + }, + "currency": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "description": "ISO 4217 currency code" + }, + "uses": { + "type": "array", + "description": "Which rights uses this pricing option covers. A single option can bundle multiple uses (e.g., likeness + voice).", + "items": { + "$ref": "../enums/right-use.json" + }, + "minItems": 1 }, "period": { - "description": "Billing period for flat_rate and time-based models", + "type": "string", "enum": [ "daily", "weekly", @@ -39,24 +40,24 @@ "annual", "one_time" ], - "type": "string" + "description": "Billing period for flat_rate and time-based models" }, - "price": { - "description": "Price amount. Interpretation depends on model: CPM = cost per 1,000 impressions, flat_rate = fixed cost per period.", + "impression_cap": { + "type": "integer", + "minimum": 1, + "description": "Maximum impressions included in this pricing option per period" + }, + "overage_cpm": { + "type": "number", "minimum": 0, - "type": "number" + "description": "CPM rate applied to impressions exceeding the impression_cap" }, - "pricing_option_id": { - "description": "Unique identifier for this pricing option. Referenced in acquire_rights and report_usage.", - "type": "string" + "description": { + "type": "string", + "description": "Human-readable description of this pricing option" }, - "uses": { - "description": "Which rights uses this pricing option covers. A single option can bundle multiple uses (e.g., likeness + voice).", - "items": { - "$ref": "../enums/right-use.json" - }, - "minItems": 1, - "type": "array" + "ext": { + "$ref": "../core/ext.json" } }, "required": [ @@ -66,6 +67,5 @@ "currency", "uses" ], - "title": "Rights Pricing Option", - "type": "object" + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/brand/rights-terms.json b/schemas/cache/brand/rights-terms.json index ba0f6b84c..f50e7763c 100644 --- a/schemas/cache/brand/rights-terms.json +++ b/schemas/cache/brand/rights-terms.json @@ -1,46 +1,22 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, + "title": "Rights Terms", "description": "Contractual terms for a rights grant. Shared between acquire_rights and update_rights responses.", + "type": "object", "properties": { - "amount": { - "minimum": 0, - "type": "number" - }, - "currency": { - "pattern": "^[A-Z]{3}$", - "type": "string" - }, - "end_date": { - "format": "date", + "pricing_option_id": { "type": "string" }, - "exclusivity": { - "additionalProperties": true, - "description": "Exclusivity terms if applicable", - "properties": { - "countries": { - "items": { - "pattern": "^[A-Z]{2}$", - "type": "string" - }, - "type": "array" - }, - "scope": { - "type": "string" - } - }, - "type": "object" - }, - "impression_cap": { - "minimum": 1, - "type": "integer" + "amount": { + "type": "number", + "minimum": 0 }, - "overage_cpm": { - "minimum": 0, - "type": "number" + "currency": { + "type": "string", + "pattern": "^[A-Z]{3}$" }, "period": { + "type": "string", "enum": [ "daily", "weekly", @@ -48,21 +24,46 @@ "quarterly", "annual", "one_time" - ], - "type": "string" - }, - "pricing_option_id": { - "type": "string" - }, - "start_date": { - "format": "date", - "type": "string" + ] }, "uses": { + "type": "array", "items": { "$ref": "../enums/right-use.json" + } + }, + "impression_cap": { + "type": "integer", + "minimum": 1 + }, + "overage_cpm": { + "type": "number", + "minimum": 0 + }, + "start_date": { + "type": "string", + "format": "date" + }, + "end_date": { + "type": "string", + "format": "date" + }, + "exclusivity": { + "type": "object", + "description": "Exclusivity terms if applicable", + "properties": { + "scope": { + "type": "string" + }, + "countries": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[A-Z]{2}$" + } + } }, - "type": "array" + "additionalProperties": true } }, "required": [ @@ -71,6 +72,5 @@ "currency", "uses" ], - "title": "Rights Terms", - "type": "object" + "additionalProperties": true } \ No newline at end of file diff --git a/schemas/cache/brand/update-rights-request.json b/schemas/cache/brand/update-rights-request.json new file mode 100644 index 000000000..90323293e --- /dev/null +++ b/schemas/cache/brand/update-rights-request.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Update Rights Request", + "description": "Modify an existing rights grant \u2014 extend dates, adjust impression caps, change pricing, or pause/resume. Parallels update_media_buy. Only the fields provided are updated; omitted fields remain unchanged.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "rights_id": { + "type": "string", + "description": "Rights grant identifier from acquire_rights response" + }, + "end_date": { + "type": "string", + "format": "date", + "description": "New end date for the rights grant (must be >= current end_date). Extending the grant may re-issue generation credentials with updated expiration." + }, + "impression_cap": { + "type": "integer", + "minimum": 1, + "description": "New impression cap for the grant. Must be >= impressions already delivered." + }, + "pricing_option_id": { + "type": "string", + "description": "Switch to a different pricing option from the original get_rights offering. The new option must be compatible with the existing grant's uses and countries." + }, + "paused": { + "type": "boolean", + "description": "Pause or resume the rights grant. When paused, generation credentials are suspended and creative delivery should stop. When resumed, credentials are re-activated." + }, + "push_notification_config": { + "$ref": "../core/push-notification-config.json", + "description": "Webhook for async update notifications if the update requires approval" + }, + "idempotency_key": { + "type": "string", + "description": "Client-generated idempotency key for safe retries. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.", + "minLength": 16, + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "idempotency_key", + "rights_id" + ], + "additionalProperties": true +} \ No newline at end of file diff --git a/schemas/cache/brand/update-rights-response.json b/schemas/cache/brand/update-rights-response.json new file mode 100644 index 000000000..5bca70983 --- /dev/null +++ b/schemas/cache/brand/update-rights-response.json @@ -0,0 +1,96 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Update Rights Response", + "description": "Result of a rights update request. Returns updated terms and re-issued credentials on success, or errors if the update cannot be applied.", + "type": "object", + "oneOf": [ + { + "title": "UpdateRightsSuccess", + "properties": { + "rights_id": { + "type": "string", + "description": "Rights grant identifier" + }, + "terms": { + "$ref": "rights-terms.json", + "description": "Updated contractual terms (same shape as acquire_rights acquired response)" + }, + "generation_credentials": { + "type": "array", + "description": "Re-issued credentials reflecting updated terms (new expiration dates, adjusted caps)", + "items": { + "$ref": "../core/generation-credential.json" + } + }, + "rights_constraint": { + "$ref": "../core/rights-constraint.json", + "description": "Updated rights constraint for re-embedding in creative manifests" + }, + "paused": { + "type": "boolean", + "description": "Whether the grant is currently paused. Included when the update changes pause state." + }, + "implementation_date": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "When changes take effect (null if pending approval from rights holder)" + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "rights_id", + "terms" + ], + "additionalProperties": true, + "not": { + "required": [ + "errors" + ] + } + }, + { + "title": "UpdateRightsError", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "../core/error.json" + }, + "minItems": 1 + }, + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + } + }, + "required": [ + "errors" + ], + "additionalProperties": true, + "not": { + "anyOf": [ + { + "required": [ + "rights_id" + ] + }, + { + "required": [ + "terms" + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/schemas/cache/bundled/content-standards/calibrate-content-request.json b/schemas/cache/bundled/content-standards/calibrate-content-request.json new file mode 100644 index 000000000..97ad32a0c --- /dev/null +++ b/schemas/cache/bundled/content-standards/calibrate-content-request.json @@ -0,0 +1,1892 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Calibrate Content Request", + "description": "Request parameters for evaluating content during calibration. Multi-turn dialogue is handled at the protocol layer via contextId.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "standards_id": { + "type": "string", + "description": "Standards configuration to calibrate against" + }, + "artifact": { + "title": "Artifact", + "description": "Artifact to evaluate", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + }, + "idempotency_key": { + "type": "string", + "description": "Client-generated unique key for at-most-once execution. If a request with the same key has already been processed, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.", + "minLength": 16, + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" + }, + "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 + }, + "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": [ + "idempotency_key", + "standards_id", + "artifact" + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.167Z", + "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 new file mode 100644 index 000000000..03707b939 --- /dev/null +++ b/schemas/cache/bundled/content-standards/calibrate-content-response.json @@ -0,0 +1,166 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Calibrate Content Response", + "description": "Response payload with verdict and detailed explanations for collaborative calibration", + "type": "object", + "oneOf": [ + { + "type": "object", + "description": "Success response with detailed calibration feedback", + "properties": { + "verdict": { + "type": "string", + "enum": [ + "pass", + "fail" + ], + "description": "Overall pass/fail verdict for the content evaluation" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Model confidence in the verdict (0-1)" + }, + "explanation": { + "type": "string", + "description": "Detailed natural language explanation of the decision" + }, + "features": { + "type": "array", + "description": "Per-feature breakdown with explanations. Mirrors validate_content_delivery feature shape so calibration loops can correlate against production verdicts by policy_id.", + "items": { + "type": "object", + "properties": { + "feature_id": { + "type": "string", + "description": "Which feature was evaluated. Data features come from the content-standards feature catalog (e.g., 'brand_safety', 'brand_suitability', 'competitor_adjacency'). Record-level structural checks use reserved namespaces: 'record:malformed_artifact'. Reserved prefixes: 'record:', 'delivery:'." + }, + "status": { + "type": "string", + "enum": [ + "passed", + "failed", + "warning", + "unevaluated" + ], + "description": "Evaluation status for this feature" + }, + "policy_id": { + "type": "string", + "description": "Policy ID that triggered this result. Enables the calibration loop to iterate on specific policies by correlating sample outcomes to policy ids." + }, + "explanation": { + "type": "string", + "description": "Human-readable explanation of why this feature passed or failed" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Optional evaluator confidence in this result (0-1). Distinguishes certain verdicts from ambiguous ones." + } + }, + "required": [ + "feature_id", + "status" + ] + } + }, + "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 + }, + "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": [ + "verdict" + ] + }, + { + "type": "object", + "description": "Error response", + "properties": { + "errors": { + "type": "array", + "items": { + "title": "Error", + "description": "Standard error structure for task-specific errors and warnings", + "type": "object", + "properties": { + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification." + }, + "message": { + "type": "string", + "description": "Human-readable error message" + }, + "field": { + "type": "string", + "description": "Field path associated with the error (e.g., 'packages[0].targeting')" + }, + "suggestion": { + "type": "string", + "description": "Suggested fix for the error" + }, + "retry_after": { + "type": "number", + "description": "Seconds to wait before retrying the operation. Sellers MUST return values between 1 and 3600. Clients MUST clamp values outside this range.", + "minimum": 1, + "maximum": 3600 + }, + "details": { + "type": "object", + "description": "Additional task-specific error details", + "additionalProperties": true + }, + "recovery": { + "type": "string", + "enum": [ + "transient", + "correctable", + "terminal" + ], + "description": "Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found)." + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + } + }, + "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 + }, + "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": [ + "errors" + ] + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.169Z", + "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 new file mode 100644 index 000000000..51b3ac619 --- /dev/null +++ b/schemas/cache/bundled/content-standards/create-content-standards-request.json @@ -0,0 +1,4143 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Create Content Standards Request", + "description": "Request parameters for creating a new content standards configuration", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "scope": { + "type": "object", + "description": "Where this standards configuration applies", + "properties": { + "countries_all": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "ISO 3166-1 alpha-2 country codes. Standards apply in ALL listed countries (AND logic)." + }, + "channels_any": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "minItems": 1, + "description": "Advertising channels. Standards apply to ANY of the listed channels (OR logic)." + }, + "languages_any": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "BCP 47 language tags (e.g., 'en', 'de', 'fr'). Standards apply to content in ANY of these languages (OR logic). Content in unlisted languages is not covered by these standards." + }, + "description": { + "type": "string", + "description": "Human-readable description of this scope" + } + }, + "required": [ + "languages_any" + ] + }, + "registry_policy_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Registry policy IDs to use as the evaluation basis for this content standard. When provided, the agent resolves policies from the registry and uses their policy text and exemplars as the evaluation criteria. The 'policy' field becomes optional when registry_policy_ids is provided." + }, + "policies": { + "type": "array", + "description": "Bespoke policies for this content-standards configuration, using the same shape as registry entries. Each policy is addressable by policy_id and carries its own enforcement (must|should); governance findings reference the policy_id that triggered them. Inline bespoke policies can omit version/name/category (defaulted by the server). Combines with registry_policy_ids \u2014 registry policies and bespoke policies are both evaluated. Bespoke policy_ids MUST be flat (no colons/slashes) to avoid collision with namespaced registry ids.", + "items": { + "title": "Policy Entry", + "description": "A policy \u2014 either published to the shared registry (with full regulatory metadata) or authored inline by a buyer for their own campaign (lightweight, metadata optional). Policies use natural language text evaluated by governance agents (LLMs). Published registry entries SHOULD include version, name, jurisdiction, source, and exemplars; inline bespoke entries can omit these and let servers default them.", + "type": "object", + "properties": { + "policy_id": { + "type": "string", + "description": "Unique identifier for this policy. Registry-published ids are canonical (e.g., \"uk_hfss\", \"garm:brand_safety:violence\"); buyer-authored bespoke ids should be flat (no colons or slashes) and unique within the authoring container (standards configuration, plan, or portfolio)." + }, + "source": { + "type": "string", + "enum": [ + "registry", + "inline" + ], + "default": "inline", + "description": "Origin of this policy. 'registry' = published to the shared AdCP policy registry with full regulatory metadata. 'inline' = authored bespoke for a specific standards configuration, plan, or portfolio. Defaults to 'inline'. Governance agents MUST set 'registry' when publishing to the registry." + }, + "version": { + "type": "string", + "description": "Semver version string (e.g., \"1.0.0\"). Incremented when policy content changes. Optional for inline bespoke policies \u2014 defaults to \"1.0.0\". SHOULD be provided for registry-published policies." + }, + "name": { + "type": "string", + "description": "Human-readable name (e.g., \"UK HFSS Restrictions\"). Optional for inline bespoke policies \u2014 servers MAY default to policy_id." + }, + "description": { + "type": "string", + "description": "Brief summary of what this policy covers." + }, + "category": { + "title": "Policy Category", + "description": "The nature of the obligation: regulation (legal requirement) or standard (best practice). Optional for inline bespoke policies \u2014 defaults to \"standard\".", + "type": "string", + "enum": [ + "regulation", + "standard" + ], + "enumDescriptions": { + "regulation": "Legal requirement with jurisdiction scope. Violations have legal consequences. Enforcement is hard (must).", + "standard": "Industry best practice, voluntary but recommended. Protects brand value and campaign effectiveness. Enforcement is soft (should)." + } + }, + "enforcement": { + "title": "Policy Enforcement Level", + "description": "How governance agents treat violations. Regulations are typically \"must\"; standards are typically \"should\".", + "type": "string", + "enum": [ + "must", + "should", + "may" + ], + "enumDescriptions": { + "must": "Legal requirement. Governance agents reject actions that violate this policy.", + "should": "Best practice. Governance agents warn on violations but do not block.", + "may": "Recommendation. Governance agents log for informational purposes only." + } + }, + "jurisdictions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ISO 3166-1 alpha-2 country codes where this policy applies. Empty array means the policy is not jurisdiction-specific." + }, + "region_aliases": { + "type": "object", + "description": "Named groups of jurisdictions for convenience (e.g., {\"EU\": [\"AT\",\"BE\",\"BG\",...]}). Governance agents expand aliases when matching against a plan's target jurisdictions.", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "policy_categories": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Regulatory categories this policy belongs to (e.g., [\"children_directed\", \"age_restricted\"]). Used for automatic matching against a campaign plan's declared policy_categories. A single policy can belong to multiple categories." + }, + "channels": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "description": "Advertising channels this policy applies to. If omitted or null, the policy applies to all channels." + }, + "governance_domains": { + "type": "array", + "items": { + "title": "Governance Domain", + "description": "Governance sub-domains that a registry policy applies to. Used to indicate which types of governance agents can evaluate this policy.", + "type": "string", + "enum": [ + "campaign", + "property", + "creative", + "content_standards" + ] + }, + "description": "Governance sub-domains this policy applies to. Determines which types of governance agents can declare registry:{policy_id} features. For example, a policy with domains [\"creative\", \"property\"] can be declared as a feature by both creative and property governance agents." + }, + "effective_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard takes effect. Before this date, governance agents treat the policy as informational (evaluate but do not block). After this date, the policy is enforced at its declared enforcement level." + }, + "sunset_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard is no longer enforced. After this date, governance agents stop evaluating this policy. Omit if the policy has no expiration." + }, + "source_url": { + "type": "string", + "format": "uri", + "description": "Link to the source regulation, standard, or legislation." + }, + "source_name": { + "type": "string", + "description": "Name of the issuing body (e.g., \"UK Food Standards Agency\", \"US Federal Trade Commission\")." + }, + "policy": { + "type": "string", + "description": "Natural language policy text describing what is required, prohibited, or recommended. Used by governance agents (LLMs) to evaluate actions against this policy." + }, + "guidance": { + "type": "string", + "description": "Implementation notes for governance agent developers. Not used in evaluation prompts." + }, + "exemplars": { + "type": "object", + "description": "Calibration examples for governance agents, following the Content Standards pattern.", + "properties": { + "pass": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that comply with this policy." + }, + "fail": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that violate this policy." + } + }, + "additionalProperties": false + }, + "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": [ + "policy_id", + "enforcement", + "policy" + ], + "additionalProperties": false, + "$defs": { + "exemplar": { + "type": "object", + "properties": { + "scenario": { + "type": "string", + "description": "A concrete scenario describing an advertising action or configuration." + }, + "explanation": { + "type": "string", + "description": "Why this scenario passes or fails the policy." + } + }, + "required": [ + "scenario", + "explanation" + ], + "additionalProperties": false + } + } + }, + "minItems": 1 + }, + "calibration_exemplars": { + "type": "object", + "description": "Training/test set to calibrate policy interpretation. Use URL references for pages to be fetched and analyzed, or full artifacts for pre-extracted content.", + "properties": { + "pass": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "description": "URL reference - specific page to fetch and evaluate", + "properties": { + "type": { + "type": "string", + "const": "url", + "description": "Indicates this is a URL reference" + }, + "value": { + "type": "string", + "format": "uri", + "description": "Full URL to a specific page (e.g., 'https://espn.com/nba/story/_/id/12345/lakers-win')" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for content at this URL" + } + }, + "required": [ + "type", + "value" + ] + }, + { + "title": "Artifact", + "description": "Full artifact with pre-extracted content (text, images, video, audio)", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + } + ] + }, + "description": "Content that passes the standards" + }, + "fail": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "description": "URL reference - specific page to fetch and evaluate", + "properties": { + "type": { + "type": "string", + "const": "url", + "description": "Indicates this is a URL reference" + }, + "value": { + "type": "string", + "format": "uri", + "description": "Full URL to a specific page (e.g., 'https://news.example.com/controversial-article')" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for content at this URL" + } + }, + "required": [ + "type", + "value" + ] + }, + { + "title": "Artifact", + "description": "Full artifact with pre-extracted content (text, images, video, audio)", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + } + ] + }, + "description": "Content that fails the standards" + } + } + }, + "idempotency_key": { + "type": "string", + "description": "Client-generated unique key for this request. Prevents duplicate content standards creation on retries. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.", + "minLength": 16, + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" + }, + "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 + }, + "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": [ + "idempotency_key", + "scope" + ], + "anyOf": [ + { + "required": [ + "policies" + ] + }, + { + "required": [ + "registry_policy_ids" + ] + } + ], + "additionalProperties": true, + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.177Z", + "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 new file mode 100644 index 000000000..6d137f7c3 --- /dev/null +++ b/schemas/cache/bundled/content-standards/create-content-standards-response.json @@ -0,0 +1,115 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Create Content Standards Response", + "description": "Response payload for creating a content standards configuration", + "type": "object", + "oneOf": [ + { + "type": "object", + "description": "Success response - returns the created standards identifier", + "properties": { + "standards_id": { + "type": "string", + "description": "Unique identifier for the created standards configuration" + }, + "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 + }, + "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": [ + "standards_id" + ] + }, + { + "type": "object", + "description": "Error response", + "properties": { + "errors": { + "type": "array", + "items": { + "title": "Error", + "description": "Standard error structure for task-specific errors and warnings", + "type": "object", + "properties": { + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification." + }, + "message": { + "type": "string", + "description": "Human-readable error message" + }, + "field": { + "type": "string", + "description": "Field path associated with the error (e.g., 'packages[0].targeting')" + }, + "suggestion": { + "type": "string", + "description": "Suggested fix for the error" + }, + "retry_after": { + "type": "number", + "description": "Seconds to wait before retrying the operation. Sellers MUST return values between 1 and 3600. Clients MUST clamp values outside this range.", + "minimum": 1, + "maximum": 3600 + }, + "details": { + "type": "object", + "description": "Additional task-specific error details", + "additionalProperties": true + }, + "recovery": { + "type": "string", + "enum": [ + "transient", + "correctable", + "terminal" + ], + "description": "Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found)." + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + } + }, + "conflicting_standards_id": { + "type": "string", + "description": "If the error is a scope conflict, the ID of the existing standards that conflict" + }, + "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 + }, + "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": [ + "errors" + ] + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.181Z", + "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 new file mode 100644 index 000000000..5343dfa4c --- /dev/null +++ b/schemas/cache/bundled/content-standards/get-content-standards-request.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Content Standards Request", + "description": "Request parameters for retrieving content safety policies", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "standards_id": { + "type": "string", + "description": "Identifier for the standards configuration to retrieve" + }, + "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 + }, + "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": [ + "standards_id" + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.182Z", + "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 new file mode 100644 index 000000000..058f507e0 --- /dev/null +++ b/schemas/cache/bundled/content-standards/get-content-standards-response.json @@ -0,0 +1,4327 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Content Standards Response", + "description": "Response payload with content safety policies", + "type": "object", + "oneOf": [ + { + "type": "object", + "description": "Success response - returns the content standards configuration", + "allOf": [ + { + "title": "Content Standards", + "description": "A content standards configuration defining brand safety and suitability policies. Standards are scoped by brand, geography, and channel. Multiple standards can be active simultaneously for different scopes.", + "type": "object", + "properties": { + "standards_id": { + "type": "string", + "description": "Unique identifier for this standards configuration" + }, + "name": { + "type": "string", + "description": "Human-readable name for this standards configuration" + }, + "countries_all": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "ISO 3166-1 alpha-2 country codes. Standards apply in ALL listed countries (AND logic)." + }, + "channels_any": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "minItems": 1, + "description": "Advertising channels. Standards apply to ANY of the listed channels (OR logic)." + }, + "languages_any": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "BCP 47 language tags (e.g., 'en', 'de', 'fr'). Standards apply to content in ANY of these languages (OR logic). Content in unlisted languages is not covered by these standards." + }, + "policies": { + "type": "array", + "description": "Bespoke policies for this content-standards configuration, using the same shape as registry entries. Each policy is addressable by policy_id; governance findings reference the policy_id that triggered them.", + "items": { + "title": "Policy Entry", + "description": "A policy \u2014 either published to the shared registry (with full regulatory metadata) or authored inline by a buyer for their own campaign (lightweight, metadata optional). Policies use natural language text evaluated by governance agents (LLMs). Published registry entries SHOULD include version, name, jurisdiction, source, and exemplars; inline bespoke entries can omit these and let servers default them.", + "type": "object", + "properties": { + "policy_id": { + "type": "string", + "description": "Unique identifier for this policy. Registry-published ids are canonical (e.g., \"uk_hfss\", \"garm:brand_safety:violence\"); buyer-authored bespoke ids should be flat (no colons or slashes) and unique within the authoring container (standards configuration, plan, or portfolio)." + }, + "source": { + "type": "string", + "enum": [ + "registry", + "inline" + ], + "default": "inline", + "description": "Origin of this policy. 'registry' = published to the shared AdCP policy registry with full regulatory metadata. 'inline' = authored bespoke for a specific standards configuration, plan, or portfolio. Defaults to 'inline'. Governance agents MUST set 'registry' when publishing to the registry." + }, + "version": { + "type": "string", + "description": "Semver version string (e.g., \"1.0.0\"). Incremented when policy content changes. Optional for inline bespoke policies \u2014 defaults to \"1.0.0\". SHOULD be provided for registry-published policies." + }, + "name": { + "type": "string", + "description": "Human-readable name (e.g., \"UK HFSS Restrictions\"). Optional for inline bespoke policies \u2014 servers MAY default to policy_id." + }, + "description": { + "type": "string", + "description": "Brief summary of what this policy covers." + }, + "category": { + "title": "Policy Category", + "description": "The nature of the obligation: regulation (legal requirement) or standard (best practice). Optional for inline bespoke policies \u2014 defaults to \"standard\".", + "type": "string", + "enum": [ + "regulation", + "standard" + ], + "enumDescriptions": { + "regulation": "Legal requirement with jurisdiction scope. Violations have legal consequences. Enforcement is hard (must).", + "standard": "Industry best practice, voluntary but recommended. Protects brand value and campaign effectiveness. Enforcement is soft (should)." + } + }, + "enforcement": { + "title": "Policy Enforcement Level", + "description": "How governance agents treat violations. Regulations are typically \"must\"; standards are typically \"should\".", + "type": "string", + "enum": [ + "must", + "should", + "may" + ], + "enumDescriptions": { + "must": "Legal requirement. Governance agents reject actions that violate this policy.", + "should": "Best practice. Governance agents warn on violations but do not block.", + "may": "Recommendation. Governance agents log for informational purposes only." + } + }, + "jurisdictions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ISO 3166-1 alpha-2 country codes where this policy applies. Empty array means the policy is not jurisdiction-specific." + }, + "region_aliases": { + "type": "object", + "description": "Named groups of jurisdictions for convenience (e.g., {\"EU\": [\"AT\",\"BE\",\"BG\",...]}). Governance agents expand aliases when matching against a plan's target jurisdictions.", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "policy_categories": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Regulatory categories this policy belongs to (e.g., [\"children_directed\", \"age_restricted\"]). Used for automatic matching against a campaign plan's declared policy_categories. A single policy can belong to multiple categories." + }, + "channels": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "description": "Advertising channels this policy applies to. If omitted or null, the policy applies to all channels." + }, + "governance_domains": { + "type": "array", + "items": { + "title": "Governance Domain", + "description": "Governance sub-domains that a registry policy applies to. Used to indicate which types of governance agents can evaluate this policy.", + "type": "string", + "enum": [ + "campaign", + "property", + "creative", + "content_standards" + ] + }, + "description": "Governance sub-domains this policy applies to. Determines which types of governance agents can declare registry:{policy_id} features. For example, a policy with domains [\"creative\", \"property\"] can be declared as a feature by both creative and property governance agents." + }, + "effective_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard takes effect. Before this date, governance agents treat the policy as informational (evaluate but do not block). After this date, the policy is enforced at its declared enforcement level." + }, + "sunset_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard is no longer enforced. After this date, governance agents stop evaluating this policy. Omit if the policy has no expiration." + }, + "source_url": { + "type": "string", + "format": "uri", + "description": "Link to the source regulation, standard, or legislation." + }, + "source_name": { + "type": "string", + "description": "Name of the issuing body (e.g., \"UK Food Standards Agency\", \"US Federal Trade Commission\")." + }, + "policy": { + "type": "string", + "description": "Natural language policy text describing what is required, prohibited, or recommended. Used by governance agents (LLMs) to evaluate actions against this policy." + }, + "guidance": { + "type": "string", + "description": "Implementation notes for governance agent developers. Not used in evaluation prompts." + }, + "exemplars": { + "type": "object", + "description": "Calibration examples for governance agents, following the Content Standards pattern.", + "properties": { + "pass": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that comply with this policy." + }, + "fail": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that violate this policy." + } + }, + "additionalProperties": false + }, + "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": [ + "policy_id", + "enforcement", + "policy" + ], + "additionalProperties": false, + "$defs": { + "exemplar": { + "type": "object", + "properties": { + "scenario": { + "type": "string", + "description": "A concrete scenario describing an advertising action or configuration." + }, + "explanation": { + "type": "string", + "description": "Why this scenario passes or fails the policy." + } + }, + "required": [ + "scenario", + "explanation" + ], + "additionalProperties": false + } + } + }, + "minItems": 1 + }, + "calibration_exemplars": { + "type": "object", + "description": "Training/test set to calibrate policy interpretation. Provides concrete examples of pass/fail decisions.", + "properties": { + "pass": { + "type": "array", + "items": { + "title": "Artifact", + "description": "Content artifact for safety and suitability evaluation. An artifact represents content adjacent to an ad placement - a news article, podcast segment, video chapter, or social post. Artifacts are collections of assets (text, images, video, audio) plus metadata and signals.", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + }, + "description": "Artifacts that pass the content standards" + }, + "fail": { + "type": "array", + "items": { + "title": "Artifact", + "description": "Content artifact for safety and suitability evaluation. An artifact represents content adjacent to an ad placement - a news article, podcast segment, video chapter, or social post. Artifacts are collections of assets (text, images, video, audio) plus metadata and signals.", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + }, + "description": "Artifacts that fail the content standards" + } + } + }, + "pricing_options": { + "type": "array", + "description": "Pricing options for this content standards service. The buyer passes the selected pricing_option_id in report_usage for billing verification.", + "items": { + "title": "Vendor Pricing Option", + "description": "A pricing option offered by a vendor agent (signals, creative, governance). Combines pricing_option_id with the pricing model fields. Pass pricing_option_id in report_usage for billing verification. All vendor discovery responses return pricing_options as an array \u2014 vendors may offer multiple options (volume tiers, context-specific rates, different models per product line).", + "allOf": [ + { + "type": "object", + "properties": { + "pricing_option_id": { + "type": "string", + "description": "Opaque identifier for this pricing option, unique within the vendor agent. Pass this in report_usage to identify which pricing option was applied." + } + }, + "required": [ + "pricing_option_id" + ] + }, + { + "title": "Vendor Pricing", + "description": "Pricing model for a vendor service. Discriminated by model: 'cpm' (fixed CPM), 'percent_of_media' (percentage of spend with optional CPM cap), 'flat_fee' (fixed charge per reporting period), or 'per_unit' (fixed price per unit of work).", + "type": "object", + "oneOf": [ + { + "title": "CpmPricing", + "description": "Fixed cost per thousand impressions", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "cpm" + }, + "cpm": { + "type": "number", + "description": "Cost per thousand impressions", + "minimum": 0 + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "cpm", + "currency" + ], + "additionalProperties": true + }, + { + "title": "PercentOfMediaPricing", + "description": "Percentage of media spend charged for this signal. When max_cpm is set, the effective rate is capped at that CPM \u2014 useful for platforms like The Trade Desk that use percent-of-media pricing with a CPM ceiling.", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "percent_of_media" + }, + "percent": { + "type": "number", + "description": "Percentage of media spend, e.g. 15 = 15%", + "minimum": 0, + "maximum": 100 + }, + "max_cpm": { + "type": "number", + "description": "Optional CPM cap. When set, the effective charge is min(percent \u00d7 media_spend_per_mille, max_cpm).", + "minimum": 0 + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code for the resulting charge", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "percent", + "currency" + ], + "additionalProperties": true + }, + { + "title": "FlatFeePricing", + "description": "Fixed charge per billing period, regardless of impressions or spend. Used for licensed data bundles and audience subscriptions.", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "flat_fee" + }, + "amount": { + "type": "number", + "description": "Fixed charge for the billing period", + "minimum": 0 + }, + "period": { + "type": "string", + "enum": [ + "monthly", + "quarterly", + "annual", + "campaign" + ], + "description": "Billing period for the flat fee." + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "amount", + "period", + "currency" + ], + "additionalProperties": true + }, + { + "title": "PerUnitPricing", + "description": "Fixed price per unit of work. Used for creative transformation (per format), AI generation (per image, per token), and rendering (per variant). The unit field describes what is counted; unit_price is the cost per one unit.", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "per_unit" + }, + "unit": { + "type": "string", + "description": "What is counted \u2014 e.g. 'format', 'image', 'token', 'variant', 'render', 'evaluation'." + }, + "unit_price": { + "type": "number", + "description": "Cost per one unit", + "minimum": 0 + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "unit", + "unit_price", + "currency" + ], + "additionalProperties": true + } + ] + } + ] + }, + "minItems": 1 + }, + "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": [ + "standards_id" + ] + } + ], + "properties": { + "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 + }, + "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 + } + } + }, + { + "type": "object", + "description": "Error response", + "properties": { + "errors": { + "type": "array", + "items": { + "title": "Error", + "description": "Standard error structure for task-specific errors and warnings", + "type": "object", + "properties": { + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification." + }, + "message": { + "type": "string", + "description": "Human-readable error message" + }, + "field": { + "type": "string", + "description": "Field path associated with the error (e.g., 'packages[0].targeting')" + }, + "suggestion": { + "type": "string", + "description": "Suggested fix for the error" + }, + "retry_after": { + "type": "number", + "description": "Seconds to wait before retrying the operation. Sellers MUST return values between 1 and 3600. Clients MUST clamp values outside this range.", + "minimum": 1, + "maximum": 3600 + }, + "details": { + "type": "object", + "description": "Additional task-specific error details", + "additionalProperties": true + }, + "recovery": { + "type": "string", + "enum": [ + "transient", + "correctable", + "terminal" + ], + "description": "Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found)." + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + } + }, + "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 + }, + "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": [ + "errors" + ] + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.190Z", + "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 new file mode 100644 index 000000000..ee3122e39 --- /dev/null +++ b/schemas/cache/bundled/content-standards/get-media-buy-artifacts-request.json @@ -0,0 +1,189 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Media Buy Artifacts Request", + "description": "Request parameters for retrieving content artifacts from a media buy for validation", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "account": { + "title": "Account Reference", + "description": "Filter artifacts to a specific account. When omitted, returns artifacts across all accessible accounts.", + "type": "object", + "oneOf": [ + { + "properties": { + "account_id": { + "type": "string", + "description": "Seller-assigned account identifier (from sync_accounts or list_accounts)" + } + }, + "required": [ + "account_id" + ], + "additionalProperties": false + }, + { + "properties": { + "brand": { + "title": "Brand Reference", + "description": "Brand reference identifying the advertiser", + "type": "object", + "properties": { + "domain": { + "type": "string", + "description": "Domain where /.well-known/brand.json is hosted, or the brand's operating domain", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$" + }, + "brand_id": { + "title": "Brand ID", + "description": "Brand identifier within the house portfolio. Optional for single-brand domains.", + "type": "string", + "pattern": "^[a-z0-9_]+$", + "examples": [ + "tide", + "cheerios", + "air_jordan", + "nike", + "pampers" + ] + } + }, + "required": [ + "domain" + ], + "additionalProperties": false, + "examples": [ + { + "domain": "nova-brands.com", + "brand_id": "spark" + }, + { + "domain": "nova-brands.com", + "brand_id": "glow" + }, + { + "domain": "acme-corp.com" + } + ] + }, + "operator": { + "type": "string", + "description": "Domain of the entity operating on the brand's behalf. When the brand operates directly, this is the brand's domain.", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$" + }, + "sandbox": { + "type": "boolean", + "description": "When true, references the sandbox account for this brand/operator pair. Defaults to false (production account).", + "default": false + } + }, + "required": [ + "brand", + "operator" + ], + "additionalProperties": false + } + ], + "examples": [ + { + "account_id": "acc_acme_001" + }, + { + "brand": { + "domain": "acme-corp.com" + }, + "operator": "acme-corp.com" + }, + { + "brand": { + "domain": "nova-brands.com", + "brand_id": "spark" + }, + "operator": "pinnacle-media.com" + }, + { + "brand": { + "domain": "acme-corp.com" + }, + "operator": "acme-corp.com", + "sandbox": true + } + ] + }, + "media_buy_id": { + "type": "string", + "description": "Media buy to get artifacts from" + }, + "package_ids": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "Filter to specific packages within the media buy" + }, + "failures_only": { + "type": "boolean", + "description": "When true, only return artifacts where the seller's local model returned local_verdict: 'fail'. Useful for auditing false positives. Not useful when the seller does not run a local evaluation model (all verdicts are 'unevaluated').", + "default": false + }, + "time_range": { + "type": "object", + "description": "Filter to specific time period", + "properties": { + "start": { + "type": "string", + "format": "date-time", + "description": "Start of time range (inclusive)" + }, + "end": { + "type": "string", + "format": "date-time", + "description": "End of time range (exclusive)" + } + } + }, + "pagination": { + "type": "object", + "description": "Pagination parameters. Uses higher limits than standard pagination because artifact result sets can be very large.", + "properties": { + "max_results": { + "type": "integer", + "minimum": 1, + "maximum": 10000, + "default": 1000, + "description": "Maximum number of artifacts to return per page" + }, + "cursor": { + "type": "string", + "description": "Opaque cursor from a previous response to fetch the next page" + } + }, + "additionalProperties": false + }, + "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 + }, + "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": [ + "media_buy_id" + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.193Z", + "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 new file mode 100644 index 000000000..2e185694c --- /dev/null +++ b/schemas/cache/bundled/content-standards/get-media-buy-artifacts-response.json @@ -0,0 +1,2061 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Media Buy Artifacts Response", + "description": "Response containing content artifacts from a media buy for validation", + "type": "object", + "oneOf": [ + { + "type": "object", + "description": "Success response with artifacts", + "properties": { + "media_buy_id": { + "type": "string", + "description": "Media buy these artifacts belong to" + }, + "artifacts": { + "type": "array", + "description": "Delivery records with full artifact content", + "items": { + "type": "object", + "properties": { + "record_id": { + "type": "string", + "description": "Unique identifier for this delivery record" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "When the delivery occurred" + }, + "package_id": { + "type": "string", + "description": "Which package this delivery belongs to" + }, + "artifact": { + "title": "Artifact", + "description": "Full artifact with content assets", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + }, + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code where delivery occurred" + }, + "channel": { + "type": "string", + "description": "Channel type (e.g., display, video, audio, social)" + }, + "brand_context": { + "type": "object", + "description": "Brand information for policy evaluation. Schema TBD - placeholder for brand identifiers.", + "properties": { + "brand_id": { + "type": "string", + "description": "Brand identifier" + }, + "sku_id": { + "type": "string", + "description": "Product/SKU identifier if applicable" + } + } + }, + "local_verdict": { + "type": "string", + "enum": [ + "pass", + "fail", + "unevaluated" + ], + "description": "Seller's local model verdict for this artifact" + } + }, + "required": [ + "record_id", + "artifact" + ] + } + }, + "collection_info": { + "type": "object", + "description": "Information about artifact collection for this media buy. Sampling is configured at buy creation time \u2014 this reports what was actually collected.", + "properties": { + "total_deliveries": { + "type": "integer", + "description": "Total deliveries in the requested time range" + }, + "total_collected": { + "type": "integer", + "description": "Total artifacts collected (per the buy's sampling configuration)" + }, + "returned_count": { + "type": "integer", + "description": "Number of artifacts in this response (may be less than total_collected due to pagination or filters)" + }, + "effective_rate": { + "type": "number", + "description": "Actual collection rate achieved (total_collected / total_deliveries)" + } + } + }, + "pagination": { + "title": "Pagination Response", + "description": "Standard cursor-based pagination metadata for list responses", + "type": "object", + "properties": { + "has_more": { + "type": "boolean", + "description": "Whether more results are available beyond this page" + }, + "cursor": { + "type": "string", + "description": "Opaque cursor to pass in the next request to fetch the next page. Only present when has_more is true." + }, + "total_count": { + "type": "integer", + "minimum": 0, + "description": "Total number of items matching the query across all pages. Optional because not all backends can efficiently compute this." + } + }, + "required": [ + "has_more" + ], + "additionalProperties": false + }, + "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 + }, + "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": [ + "media_buy_id", + "artifacts" + ] + }, + { + "type": "object", + "description": "Error response", + "properties": { + "errors": { + "type": "array", + "items": { + "title": "Error", + "description": "Standard error structure for task-specific errors and warnings", + "type": "object", + "properties": { + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification." + }, + "message": { + "type": "string", + "description": "Human-readable error message" + }, + "field": { + "type": "string", + "description": "Field path associated with the error (e.g., 'packages[0].targeting')" + }, + "suggestion": { + "type": "string", + "description": "Suggested fix for the error" + }, + "retry_after": { + "type": "number", + "description": "Seconds to wait before retrying the operation. Sellers MUST return values between 1 and 3600. Clients MUST clamp values outside this range.", + "minimum": 1, + "maximum": 3600 + }, + "details": { + "type": "object", + "description": "Additional task-specific error details", + "additionalProperties": true + }, + "recovery": { + "type": "string", + "enum": [ + "transient", + "correctable", + "terminal" + ], + "description": "Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found)." + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + } + }, + "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 + }, + "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": [ + "errors" + ] + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.196Z", + "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 new file mode 100644 index 000000000..556c0db37 --- /dev/null +++ b/schemas/cache/bundled/content-standards/list-content-standards-request.json @@ -0,0 +1,120 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "List Content Standards Request", + "description": "Request parameters for listing content standards configurations", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "channels": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "minItems": 1, + "description": "Filter by channel" + }, + "languages": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "Filter by BCP 47 language tags" + }, + "countries": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "Filter by ISO 3166-1 alpha-2 country codes" + }, + "pagination": { + "title": "Pagination Request", + "description": "Standard cursor-based pagination parameters for list operations", + "type": "object", + "properties": { + "max_results": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50, + "description": "Maximum number of items to return per page" + }, + "cursor": { + "type": "string", + "description": "Opaque cursor from a previous response to fetch the next page" + } + }, + "additionalProperties": false + }, + "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 + }, + "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, + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.197Z", + "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 new file mode 100644 index 000000000..1180b41f0 --- /dev/null +++ b/schemas/cache/bundled/content-standards/list-content-standards-response.json @@ -0,0 +1,4356 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "List Content Standards Response", + "description": "Response payload with list of content standards configurations", + "type": "object", + "oneOf": [ + { + "type": "object", + "description": "Success response - returns array of content standards", + "properties": { + "standards": { + "type": "array", + "items": { + "title": "Content Standards", + "description": "A content standards configuration defining brand safety and suitability policies. Standards are scoped by brand, geography, and channel. Multiple standards can be active simultaneously for different scopes.", + "type": "object", + "properties": { + "standards_id": { + "type": "string", + "description": "Unique identifier for this standards configuration" + }, + "name": { + "type": "string", + "description": "Human-readable name for this standards configuration" + }, + "countries_all": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "ISO 3166-1 alpha-2 country codes. Standards apply in ALL listed countries (AND logic)." + }, + "channels_any": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "minItems": 1, + "description": "Advertising channels. Standards apply to ANY of the listed channels (OR logic)." + }, + "languages_any": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "BCP 47 language tags (e.g., 'en', 'de', 'fr'). Standards apply to content in ANY of these languages (OR logic). Content in unlisted languages is not covered by these standards." + }, + "policies": { + "type": "array", + "description": "Bespoke policies for this content-standards configuration, using the same shape as registry entries. Each policy is addressable by policy_id; governance findings reference the policy_id that triggered them.", + "items": { + "title": "Policy Entry", + "description": "A policy \u2014 either published to the shared registry (with full regulatory metadata) or authored inline by a buyer for their own campaign (lightweight, metadata optional). Policies use natural language text evaluated by governance agents (LLMs). Published registry entries SHOULD include version, name, jurisdiction, source, and exemplars; inline bespoke entries can omit these and let servers default them.", + "type": "object", + "properties": { + "policy_id": { + "type": "string", + "description": "Unique identifier for this policy. Registry-published ids are canonical (e.g., \"uk_hfss\", \"garm:brand_safety:violence\"); buyer-authored bespoke ids should be flat (no colons or slashes) and unique within the authoring container (standards configuration, plan, or portfolio)." + }, + "source": { + "type": "string", + "enum": [ + "registry", + "inline" + ], + "default": "inline", + "description": "Origin of this policy. 'registry' = published to the shared AdCP policy registry with full regulatory metadata. 'inline' = authored bespoke for a specific standards configuration, plan, or portfolio. Defaults to 'inline'. Governance agents MUST set 'registry' when publishing to the registry." + }, + "version": { + "type": "string", + "description": "Semver version string (e.g., \"1.0.0\"). Incremented when policy content changes. Optional for inline bespoke policies \u2014 defaults to \"1.0.0\". SHOULD be provided for registry-published policies." + }, + "name": { + "type": "string", + "description": "Human-readable name (e.g., \"UK HFSS Restrictions\"). Optional for inline bespoke policies \u2014 servers MAY default to policy_id." + }, + "description": { + "type": "string", + "description": "Brief summary of what this policy covers." + }, + "category": { + "title": "Policy Category", + "description": "The nature of the obligation: regulation (legal requirement) or standard (best practice). Optional for inline bespoke policies \u2014 defaults to \"standard\".", + "type": "string", + "enum": [ + "regulation", + "standard" + ], + "enumDescriptions": { + "regulation": "Legal requirement with jurisdiction scope. Violations have legal consequences. Enforcement is hard (must).", + "standard": "Industry best practice, voluntary but recommended. Protects brand value and campaign effectiveness. Enforcement is soft (should)." + } + }, + "enforcement": { + "title": "Policy Enforcement Level", + "description": "How governance agents treat violations. Regulations are typically \"must\"; standards are typically \"should\".", + "type": "string", + "enum": [ + "must", + "should", + "may" + ], + "enumDescriptions": { + "must": "Legal requirement. Governance agents reject actions that violate this policy.", + "should": "Best practice. Governance agents warn on violations but do not block.", + "may": "Recommendation. Governance agents log for informational purposes only." + } + }, + "jurisdictions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ISO 3166-1 alpha-2 country codes where this policy applies. Empty array means the policy is not jurisdiction-specific." + }, + "region_aliases": { + "type": "object", + "description": "Named groups of jurisdictions for convenience (e.g., {\"EU\": [\"AT\",\"BE\",\"BG\",...]}). Governance agents expand aliases when matching against a plan's target jurisdictions.", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "policy_categories": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Regulatory categories this policy belongs to (e.g., [\"children_directed\", \"age_restricted\"]). Used for automatic matching against a campaign plan's declared policy_categories. A single policy can belong to multiple categories." + }, + "channels": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "description": "Advertising channels this policy applies to. If omitted or null, the policy applies to all channels." + }, + "governance_domains": { + "type": "array", + "items": { + "title": "Governance Domain", + "description": "Governance sub-domains that a registry policy applies to. Used to indicate which types of governance agents can evaluate this policy.", + "type": "string", + "enum": [ + "campaign", + "property", + "creative", + "content_standards" + ] + }, + "description": "Governance sub-domains this policy applies to. Determines which types of governance agents can declare registry:{policy_id} features. For example, a policy with domains [\"creative\", \"property\"] can be declared as a feature by both creative and property governance agents." + }, + "effective_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard takes effect. Before this date, governance agents treat the policy as informational (evaluate but do not block). After this date, the policy is enforced at its declared enforcement level." + }, + "sunset_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard is no longer enforced. After this date, governance agents stop evaluating this policy. Omit if the policy has no expiration." + }, + "source_url": { + "type": "string", + "format": "uri", + "description": "Link to the source regulation, standard, or legislation." + }, + "source_name": { + "type": "string", + "description": "Name of the issuing body (e.g., \"UK Food Standards Agency\", \"US Federal Trade Commission\")." + }, + "policy": { + "type": "string", + "description": "Natural language policy text describing what is required, prohibited, or recommended. Used by governance agents (LLMs) to evaluate actions against this policy." + }, + "guidance": { + "type": "string", + "description": "Implementation notes for governance agent developers. Not used in evaluation prompts." + }, + "exemplars": { + "type": "object", + "description": "Calibration examples for governance agents, following the Content Standards pattern.", + "properties": { + "pass": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that comply with this policy." + }, + "fail": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that violate this policy." + } + }, + "additionalProperties": false + }, + "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": [ + "policy_id", + "enforcement", + "policy" + ], + "additionalProperties": false, + "$defs": { + "exemplar": { + "type": "object", + "properties": { + "scenario": { + "type": "string", + "description": "A concrete scenario describing an advertising action or configuration." + }, + "explanation": { + "type": "string", + "description": "Why this scenario passes or fails the policy." + } + }, + "required": [ + "scenario", + "explanation" + ], + "additionalProperties": false + } + } + }, + "minItems": 1 + }, + "calibration_exemplars": { + "type": "object", + "description": "Training/test set to calibrate policy interpretation. Provides concrete examples of pass/fail decisions.", + "properties": { + "pass": { + "type": "array", + "items": { + "title": "Artifact", + "description": "Content artifact for safety and suitability evaluation. An artifact represents content adjacent to an ad placement - a news article, podcast segment, video chapter, or social post. Artifacts are collections of assets (text, images, video, audio) plus metadata and signals.", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + }, + "description": "Artifacts that pass the content standards" + }, + "fail": { + "type": "array", + "items": { + "title": "Artifact", + "description": "Content artifact for safety and suitability evaluation. An artifact represents content adjacent to an ad placement - a news article, podcast segment, video chapter, or social post. Artifacts are collections of assets (text, images, video, audio) plus metadata and signals.", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + }, + "description": "Artifacts that fail the content standards" + } + } + }, + "pricing_options": { + "type": "array", + "description": "Pricing options for this content standards service. The buyer passes the selected pricing_option_id in report_usage for billing verification.", + "items": { + "title": "Vendor Pricing Option", + "description": "A pricing option offered by a vendor agent (signals, creative, governance). Combines pricing_option_id with the pricing model fields. Pass pricing_option_id in report_usage for billing verification. All vendor discovery responses return pricing_options as an array \u2014 vendors may offer multiple options (volume tiers, context-specific rates, different models per product line).", + "allOf": [ + { + "type": "object", + "properties": { + "pricing_option_id": { + "type": "string", + "description": "Opaque identifier for this pricing option, unique within the vendor agent. Pass this in report_usage to identify which pricing option was applied." + } + }, + "required": [ + "pricing_option_id" + ] + }, + { + "title": "Vendor Pricing", + "description": "Pricing model for a vendor service. Discriminated by model: 'cpm' (fixed CPM), 'percent_of_media' (percentage of spend with optional CPM cap), 'flat_fee' (fixed charge per reporting period), or 'per_unit' (fixed price per unit of work).", + "type": "object", + "oneOf": [ + { + "title": "CpmPricing", + "description": "Fixed cost per thousand impressions", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "cpm" + }, + "cpm": { + "type": "number", + "description": "Cost per thousand impressions", + "minimum": 0 + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "cpm", + "currency" + ], + "additionalProperties": true + }, + { + "title": "PercentOfMediaPricing", + "description": "Percentage of media spend charged for this signal. When max_cpm is set, the effective rate is capped at that CPM \u2014 useful for platforms like The Trade Desk that use percent-of-media pricing with a CPM ceiling.", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "percent_of_media" + }, + "percent": { + "type": "number", + "description": "Percentage of media spend, e.g. 15 = 15%", + "minimum": 0, + "maximum": 100 + }, + "max_cpm": { + "type": "number", + "description": "Optional CPM cap. When set, the effective charge is min(percent \u00d7 media_spend_per_mille, max_cpm).", + "minimum": 0 + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code for the resulting charge", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "percent", + "currency" + ], + "additionalProperties": true + }, + { + "title": "FlatFeePricing", + "description": "Fixed charge per billing period, regardless of impressions or spend. Used for licensed data bundles and audience subscriptions.", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "flat_fee" + }, + "amount": { + "type": "number", + "description": "Fixed charge for the billing period", + "minimum": 0 + }, + "period": { + "type": "string", + "enum": [ + "monthly", + "quarterly", + "annual", + "campaign" + ], + "description": "Billing period for the flat fee." + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "amount", + "period", + "currency" + ], + "additionalProperties": true + }, + { + "title": "PerUnitPricing", + "description": "Fixed price per unit of work. Used for creative transformation (per format), AI generation (per image, per token), and rendering (per variant). The unit field describes what is counted; unit_price is the cost per one unit.", + "type": "object", + "properties": { + "model": { + "type": "string", + "const": "per_unit" + }, + "unit": { + "type": "string", + "description": "What is counted \u2014 e.g. 'format', 'image', 'token', 'variant', 'render', 'evaluation'." + }, + "unit_price": { + "type": "number", + "description": "Cost per one unit", + "minimum": 0 + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code", + "pattern": "^[A-Z]{3}$" + }, + "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": [ + "model", + "unit", + "unit_price", + "currency" + ], + "additionalProperties": true + } + ] + } + ] + }, + "minItems": 1 + }, + "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": [ + "standards_id" + ] + }, + "description": "Array of content standards configurations matching the filter criteria" + }, + "pagination": { + "title": "Pagination Response", + "description": "Standard cursor-based pagination metadata for list responses", + "type": "object", + "properties": { + "has_more": { + "type": "boolean", + "description": "Whether more results are available beyond this page" + }, + "cursor": { + "type": "string", + "description": "Opaque cursor to pass in the next request to fetch the next page. Only present when has_more is true." + }, + "total_count": { + "type": "integer", + "minimum": 0, + "description": "Total number of items matching the query across all pages. Optional because not all backends can efficiently compute this." + } + }, + "required": [ + "has_more" + ], + "additionalProperties": false + }, + "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 + }, + "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": [ + "standards" + ] + }, + { + "type": "object", + "description": "Error response", + "properties": { + "errors": { + "type": "array", + "items": { + "title": "Error", + "description": "Standard error structure for task-specific errors and warnings", + "type": "object", + "properties": { + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification." + }, + "message": { + "type": "string", + "description": "Human-readable error message" + }, + "field": { + "type": "string", + "description": "Field path associated with the error (e.g., 'packages[0].targeting')" + }, + "suggestion": { + "type": "string", + "description": "Suggested fix for the error" + }, + "retry_after": { + "type": "number", + "description": "Seconds to wait before retrying the operation. Sellers MUST return values between 1 and 3600. Clients MUST clamp values outside this range.", + "minimum": 1, + "maximum": 3600 + }, + "details": { + "type": "object", + "description": "Additional task-specific error details", + "additionalProperties": true + }, + "recovery": { + "type": "string", + "enum": [ + "transient", + "correctable", + "terminal" + ], + "description": "Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found)." + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + } + }, + "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 + }, + "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": [ + "errors" + ] + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.202Z", + "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 new file mode 100644 index 000000000..db93feb59 --- /dev/null +++ b/schemas/cache/bundled/content-standards/update-content-standards-request.json @@ -0,0 +1,4132 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Update Content Standards Request", + "description": "Request parameters for updating an existing content standards configuration. Creates a new version.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "standards_id": { + "type": "string", + "description": "ID of the standards configuration to update" + }, + "scope": { + "type": "object", + "description": "Updated scope for where this standards configuration applies", + "properties": { + "countries_all": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "ISO 3166-1 alpha-2 country codes. Standards apply in ALL listed countries (AND logic)." + }, + "channels_any": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "minItems": 1, + "description": "Advertising channels. Standards apply to ANY of the listed channels (OR logic)." + }, + "languages_any": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "BCP 47 language tags (e.g., 'en', 'de', 'fr'). Standards apply to content in ANY of these languages (OR logic). Content in unlisted languages is not covered by these standards." + }, + "description": { + "type": "string", + "description": "Human-readable description of this scope" + } + } + }, + "registry_policy_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Registry policy IDs to use as the evaluation basis. When provided, the agent resolves policies from the registry and uses their policy text and exemplars as the evaluation criteria." + }, + "policies": { + "type": "array", + "description": "Updated bespoke policies for this content-standards configuration, using the same shape as registry entries. Replaces the existing policies array; use stable policy_ids to track policies across versions. Combines with registry_policy_ids. Bespoke policy_ids MUST be flat (no colons/slashes).", + "items": { + "title": "Policy Entry", + "description": "A policy \u2014 either published to the shared registry (with full regulatory metadata) or authored inline by a buyer for their own campaign (lightweight, metadata optional). Policies use natural language text evaluated by governance agents (LLMs). Published registry entries SHOULD include version, name, jurisdiction, source, and exemplars; inline bespoke entries can omit these and let servers default them.", + "type": "object", + "properties": { + "policy_id": { + "type": "string", + "description": "Unique identifier for this policy. Registry-published ids are canonical (e.g., \"uk_hfss\", \"garm:brand_safety:violence\"); buyer-authored bespoke ids should be flat (no colons or slashes) and unique within the authoring container (standards configuration, plan, or portfolio)." + }, + "source": { + "type": "string", + "enum": [ + "registry", + "inline" + ], + "default": "inline", + "description": "Origin of this policy. 'registry' = published to the shared AdCP policy registry with full regulatory metadata. 'inline' = authored bespoke for a specific standards configuration, plan, or portfolio. Defaults to 'inline'. Governance agents MUST set 'registry' when publishing to the registry." + }, + "version": { + "type": "string", + "description": "Semver version string (e.g., \"1.0.0\"). Incremented when policy content changes. Optional for inline bespoke policies \u2014 defaults to \"1.0.0\". SHOULD be provided for registry-published policies." + }, + "name": { + "type": "string", + "description": "Human-readable name (e.g., \"UK HFSS Restrictions\"). Optional for inline bespoke policies \u2014 servers MAY default to policy_id." + }, + "description": { + "type": "string", + "description": "Brief summary of what this policy covers." + }, + "category": { + "title": "Policy Category", + "description": "The nature of the obligation: regulation (legal requirement) or standard (best practice). Optional for inline bespoke policies \u2014 defaults to \"standard\".", + "type": "string", + "enum": [ + "regulation", + "standard" + ], + "enumDescriptions": { + "regulation": "Legal requirement with jurisdiction scope. Violations have legal consequences. Enforcement is hard (must).", + "standard": "Industry best practice, voluntary but recommended. Protects brand value and campaign effectiveness. Enforcement is soft (should)." + } + }, + "enforcement": { + "title": "Policy Enforcement Level", + "description": "How governance agents treat violations. Regulations are typically \"must\"; standards are typically \"should\".", + "type": "string", + "enum": [ + "must", + "should", + "may" + ], + "enumDescriptions": { + "must": "Legal requirement. Governance agents reject actions that violate this policy.", + "should": "Best practice. Governance agents warn on violations but do not block.", + "may": "Recommendation. Governance agents log for informational purposes only." + } + }, + "jurisdictions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ISO 3166-1 alpha-2 country codes where this policy applies. Empty array means the policy is not jurisdiction-specific." + }, + "region_aliases": { + "type": "object", + "description": "Named groups of jurisdictions for convenience (e.g., {\"EU\": [\"AT\",\"BE\",\"BG\",...]}). Governance agents expand aliases when matching against a plan's target jurisdictions.", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "policy_categories": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Regulatory categories this policy belongs to (e.g., [\"children_directed\", \"age_restricted\"]). Used for automatic matching against a campaign plan's declared policy_categories. A single policy can belong to multiple categories." + }, + "channels": { + "type": "array", + "items": { + "title": "Media Channel", + "description": "Standardized advertising media channels describing how buyers allocate budget. Channels are planning abstractions, not technical substrates. See the Media Channel Taxonomy specification for detailed definitions.", + "type": "string", + "enum": [ + "display", + "olv", + "social", + "search", + "ctv", + "linear_tv", + "radio", + "streaming_audio", + "podcast", + "dooh", + "ooh", + "print", + "cinema", + "email", + "gaming", + "retail_media", + "influencer", + "affiliate", + "product_placement", + "sponsored_intelligence" + ], + "enumDescriptions": { + "display": "Digital display advertising (banners, native, rich media) across web and app", + "olv": "Online video advertising outside CTV (pre-roll, outstream, in-app video)", + "social": "Social media platforms (Facebook, Instagram, TikTok, LinkedIn, etc.)", + "search": "Search engine advertising and search networks", + "ctv": "Connected TV and streaming on television screens", + "linear_tv": "Traditional broadcast and cable television", + "radio": "Traditional AM/FM radio broadcast", + "streaming_audio": "Digital audio streaming services (Spotify, Pandora, etc.)", + "podcast": "Podcast advertising (host-read or dynamically inserted)", + "dooh": "Digital out-of-home screens in public spaces", + "ooh": "Classic out-of-home (physical billboards, transit, etc.)", + "print": "Newspapers, magazines, and other print publications", + "cinema": "Movie theater advertising", + "email": "Email advertising and sponsored newsletter content", + "gaming": "In-game advertising across platforms", + "retail_media": "Retail media networks and commerce marketplaces (Amazon, Walmart, Instacart)", + "influencer": "Creator and influencer marketing partnerships", + "affiliate": "Affiliate networks, comparison sites, and performance-based partnerships", + "product_placement": "Product placement, branded content, and sponsorship integrations", + "sponsored_intelligence": "Sponsored Intelligence \u2014 advertising within AI assistants, AI search, and generative AI experiences via the reversed data flow" + } + }, + "description": "Advertising channels this policy applies to. If omitted or null, the policy applies to all channels." + }, + "governance_domains": { + "type": "array", + "items": { + "title": "Governance Domain", + "description": "Governance sub-domains that a registry policy applies to. Used to indicate which types of governance agents can evaluate this policy.", + "type": "string", + "enum": [ + "campaign", + "property", + "creative", + "content_standards" + ] + }, + "description": "Governance sub-domains this policy applies to. Determines which types of governance agents can declare registry:{policy_id} features. For example, a policy with domains [\"creative\", \"property\"] can be declared as a feature by both creative and property governance agents." + }, + "effective_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard takes effect. Before this date, governance agents treat the policy as informational (evaluate but do not block). After this date, the policy is enforced at its declared enforcement level." + }, + "sunset_date": { + "type": "string", + "format": "date", + "description": "ISO 8601 date when the regulation or standard is no longer enforced. After this date, governance agents stop evaluating this policy. Omit if the policy has no expiration." + }, + "source_url": { + "type": "string", + "format": "uri", + "description": "Link to the source regulation, standard, or legislation." + }, + "source_name": { + "type": "string", + "description": "Name of the issuing body (e.g., \"UK Food Standards Agency\", \"US Federal Trade Commission\")." + }, + "policy": { + "type": "string", + "description": "Natural language policy text describing what is required, prohibited, or recommended. Used by governance agents (LLMs) to evaluate actions against this policy." + }, + "guidance": { + "type": "string", + "description": "Implementation notes for governance agent developers. Not used in evaluation prompts." + }, + "exemplars": { + "type": "object", + "description": "Calibration examples for governance agents, following the Content Standards pattern.", + "properties": { + "pass": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that comply with this policy." + }, + "fail": { + "type": "array", + "items": { + "$ref": "#/$defs/exemplar" + }, + "description": "Scenarios that violate this policy." + } + }, + "additionalProperties": false + }, + "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": [ + "policy_id", + "enforcement", + "policy" + ], + "additionalProperties": false, + "$defs": { + "exemplar": { + "type": "object", + "properties": { + "scenario": { + "type": "string", + "description": "A concrete scenario describing an advertising action or configuration." + }, + "explanation": { + "type": "string", + "description": "Why this scenario passes or fails the policy." + } + }, + "required": [ + "scenario", + "explanation" + ], + "additionalProperties": false + } + } + }, + "minItems": 1 + }, + "calibration_exemplars": { + "type": "object", + "description": "Updated training/test set to calibrate policy interpretation. Use URL references for pages to be fetched and analyzed, or full artifacts for pre-extracted content.", + "properties": { + "pass": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "description": "URL reference - specific page to fetch and evaluate", + "properties": { + "type": { + "type": "string", + "const": "url", + "description": "Indicates this is a URL reference" + }, + "value": { + "type": "string", + "format": "uri", + "description": "Full URL to a specific page (e.g., 'https://espn.com/nba/story/_/id/12345/lakers-win')" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for content at this URL" + } + }, + "required": [ + "type", + "value" + ] + }, + { + "title": "Artifact", + "description": "Full artifact with pre-extracted content (text, images, video, audio)", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + } + ] + }, + "description": "Content that passes the standards" + }, + "fail": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "description": "URL reference - specific page to fetch and evaluate", + "properties": { + "type": { + "type": "string", + "const": "url", + "description": "Indicates this is a URL reference" + }, + "value": { + "type": "string", + "format": "uri", + "description": "Full URL to a specific page (e.g., 'https://news.example.com/controversial-article')" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for content at this URL" + } + }, + "required": [ + "type", + "value" + ] + }, + { + "title": "Artifact", + "description": "Full artifact with pre-extracted content (text, images, video, audio)", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + } + ] + }, + "description": "Content that fails the standards" + } + } + }, + "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 + }, + "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 + }, + "idempotency_key": { + "type": "string", + "description": "Client-generated unique key for at-most-once execution. If a request with the same key has already been processed, the server returns the original response without re-processing. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.", + "minLength": 16, + "maxLength": 255, + "pattern": "^[A-Za-z0-9_.:-]{16,255}$" + } + }, + "required": [ + "idempotency_key", + "standards_id" + ], + "additionalProperties": true, + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.210Z", + "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 new file mode 100644 index 000000000..71211aa1b --- /dev/null +++ b/schemas/cache/bundled/content-standards/update-content-standards-response.json @@ -0,0 +1,130 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Update Content Standards Response", + "description": "Response from updating a content standards configuration", + "oneOf": [ + { + "title": "UpdateContentStandardsSuccess", + "type": "object", + "properties": { + "success": { + "type": "boolean", + "const": true, + "description": "Indicates the update was applied successfully" + }, + "standards_id": { + "type": "string", + "description": "ID of the updated standards configuration" + }, + "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 + }, + "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": [ + "success", + "standards_id" + ], + "additionalProperties": true + }, + { + "title": "UpdateContentStandardsError", + "type": "object", + "properties": { + "success": { + "type": "boolean", + "const": false, + "description": "Indicates the update failed" + }, + "errors": { + "type": "array", + "items": { + "title": "Error", + "description": "Standard error structure for task-specific errors and warnings", + "type": "object", + "properties": { + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification." + }, + "message": { + "type": "string", + "description": "Human-readable error message" + }, + "field": { + "type": "string", + "description": "Field path associated with the error (e.g., 'packages[0].targeting')" + }, + "suggestion": { + "type": "string", + "description": "Suggested fix for the error" + }, + "retry_after": { + "type": "number", + "description": "Seconds to wait before retrying the operation. Sellers MUST return values between 1 and 3600. Clients MUST clamp values outside this range.", + "minimum": 1, + "maximum": 3600 + }, + "details": { + "type": "object", + "description": "Additional task-specific error details", + "additionalProperties": true + }, + "recovery": { + "type": "string", + "enum": [ + "transient", + "correctable", + "terminal" + ], + "description": "Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found)." + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + }, + "description": "Errors that occurred during the update", + "minItems": 1 + }, + "conflicting_standards_id": { + "type": "string", + "description": "If scope change conflicts with another configuration, the ID of the conflicting standards" + }, + "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 + }, + "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": [ + "success", + "errors" + ], + "additionalProperties": true + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.214Z", + "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 new file mode 100644 index 000000000..cabe25e88 --- /dev/null +++ b/schemas/cache/bundled/content-standards/validate-content-delivery-request.json @@ -0,0 +1,1947 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Validate Content Delivery Request", + "description": "Request parameters for batch validating delivery records against content safety policies", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "standards_id": { + "type": "string", + "description": "Standards configuration to validate against" + }, + "records": { + "type": "array", + "description": "Delivery records to validate (max 10,000)", + "minItems": 1, + "maxItems": 10000, + "items": { + "type": "object", + "properties": { + "record_id": { + "type": "string", + "description": "Unique identifier for this delivery record" + }, + "media_buy_id": { + "type": "string", + "description": "Media buy this record belongs to (when batching across multiple buys)" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "When the delivery occurred" + }, + "artifact": { + "title": "Artifact", + "description": "Artifact where ad was delivered", + "type": "object", + "properties": { + "property_rid": { + "type": "string", + "description": "Stable property identifier from the property catalog. Globally unique across the ecosystem." + }, + "artifact_id": { + "type": "string", + "description": "Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')." + }, + "variant_id": { + "type": "string", + "description": "Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique." + }, + "format_id": { + "title": "Format ID", + "description": "Optional reference to a format definition. Uses the same format registry as creative formats.", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "url": { + "type": "string", + "format": "uri", + "description": "Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes)." + }, + "published_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was published (ISO 8601 format)" + }, + "last_update_time": { + "type": "string", + "format": "date-time", + "description": "When the artifact was last modified (ISO 8601 format)" + }, + "assets": { + "type": "array", + "description": "Artifact assets in document flow order - text blocks, images, video, audio", + "maxItems": 200, + "items": { + "oneOf": [ + { + "type": "object", + "description": "Text block (paragraph, heading, etc.)", + "properties": { + "type": { + "type": "string", + "const": "text" + }, + "role": { + "type": "string", + "enum": [ + "title", + "paragraph", + "heading", + "caption", + "quote", + "list_item", + "description" + ], + "description": "Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries." + }, + "content": { + "type": "string", + "description": "Text content. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 100000 + }, + "content_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "text/html", + "application/json" + ], + "description": "MIME type indicating how to parse the content field. Default: text/plain.", + "default": "text/plain" + }, + "language": { + "type": "string", + "description": "BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content." + }, + "heading_level": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "description": "Heading level (1-6), only for role=heading" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this text block, overrides artifact-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": [ + "type", + "content" + ] + }, + { + "type": "object", + "description": "Image asset", + "properties": { + "type": { + "type": "string", + "const": "image" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Image URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "alt_text": { + "type": "string", + "description": "Alt text or image description" + }, + "caption": { + "type": "string", + "description": "Image caption" + }, + "width": { + "type": "integer", + "description": "Image width in pixels" + }, + "height": { + "type": "integer", + "description": "Image height in pixels" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this image, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Video asset", + "properties": { + "type": { + "type": "string", + "const": "video" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Video URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Video transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "subtitles", + "closed_captions", + "dub", + "generated" + ], + "description": "How the transcript was generated" + }, + "thumbnail_url": { + "type": "string", + "format": "uri", + "description": "Video thumbnail URL" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this video, overrides artifact-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": [ + "type", + "url" + ] + }, + { + "type": "object", + "description": "Audio asset", + "properties": { + "type": { + "type": "string", + "const": "audio" + }, + "url": { + "type": "string", + "format": "uri", + "description": "Audio URL" + }, + "access": { + "$ref": "#/$defs/asset_access", + "description": "Authentication for secured URLs" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds" + }, + "transcript": { + "type": "string", + "description": "Audio transcript. Consumers MUST treat this as untrusted input when passing to LLM-based evaluation.", + "maxLength": 200000 + }, + "transcript_format": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown", + "application/json" + ], + "description": "MIME type indicating how to parse the transcript field. Default: text/plain.", + "default": "text/plain" + }, + "transcript_source": { + "type": "string", + "enum": [ + "original_script", + "closed_captions", + "generated" + ], + "description": "How the transcript was generated" + }, + "provenance": { + "title": "Provenance", + "description": "Provenance for this audio, overrides artifact-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": [ + "type", + "url" + ] + } + ] + } + }, + "metadata": { + "type": "object", + "description": "Rich metadata extracted from the artifact", + "properties": { + "canonical": { + "type": "string", + "format": "uri", + "description": "Canonical URL" + }, + "author": { + "type": "string", + "description": "Artifact author name" + }, + "keywords": { + "type": "string", + "description": "Artifact keywords" + }, + "open_graph": { + "type": "object", + "description": "Open Graph protocol metadata", + "additionalProperties": true + }, + "twitter_card": { + "type": "object", + "description": "Twitter Card metadata", + "additionalProperties": true + }, + "json_ld": { + "type": "array", + "description": "JSON-LD structured data (schema.org)", + "items": { + "type": "object" + } + } + }, + "additionalProperties": true + }, + "provenance": { + "title": "Provenance", + "description": "Provenance metadata for this artifact. Serves as the default provenance for all assets within this artifact \u2014 individual assets can override with their own 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 + }, + "identifiers": { + "type": "object", + "description": "Platform-specific identifiers for this artifact", + "properties": { + "apple_podcast_id": { + "type": "string", + "description": "Apple Podcasts ID" + }, + "spotify_collection_id": { + "type": "string", + "description": "Spotify collection ID" + }, + "podcast_guid": { + "type": "string", + "description": "Podcast GUID (from RSS feed)" + }, + "youtube_video_id": { + "type": "string", + "description": "YouTube video ID" + }, + "rss_url": { + "type": "string", + "format": "uri", + "description": "RSS feed URL" + } + }, + "additionalProperties": true + } + }, + "required": [ + "property_rid", + "artifact_id", + "assets" + ], + "additionalProperties": true, + "$defs": { + "asset_access": { + "type": "object", + "description": "Authentication for accessing secured asset URLs", + "oneOf": [ + { + "type": "object", + "description": "Bearer token authentication", + "properties": { + "method": { + "type": "string", + "const": "bearer_token" + }, + "token": { + "type": "string", + "description": "OAuth2 bearer token for Authorization header" + } + }, + "required": [ + "method", + "token" + ] + }, + { + "type": "object", + "description": "Service account authentication (GCP, AWS)", + "properties": { + "method": { + "type": "string", + "const": "service_account" + }, + "provider": { + "type": "string", + "enum": [ + "gcp", + "aws" + ], + "description": "Cloud provider" + }, + "credentials": { + "type": "object", + "description": "Service account credentials", + "additionalProperties": true + } + }, + "required": [ + "method", + "provider" + ] + }, + { + "type": "object", + "description": "Pre-signed URL (credentials embedded in URL)", + "properties": { + "method": { + "type": "string", + "const": "signed_url" + } + }, + "required": [ + "method" + ] + } + ] + } + } + }, + "country": { + "type": "string", + "description": "ISO 3166-1 alpha-2 country code where delivery occurred" + }, + "channel": { + "type": "string", + "description": "Channel type (e.g., display, video, audio, social)" + }, + "brand_context": { + "type": "object", + "description": "Brand information for policy evaluation. Schema TBD - placeholder for brand identifiers.", + "properties": { + "brand_id": { + "type": "string", + "description": "Brand identifier" + }, + "sku_id": { + "type": "string", + "description": "Product/SKU identifier if applicable" + } + } + } + }, + "required": [ + "record_id", + "artifact" + ] + } + }, + "feature_ids": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "description": "Specific features to evaluate (defaults to all)" + }, + "include_passed": { + "type": "boolean", + "default": true, + "description": "Include passed records in results" + }, + "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 + }, + "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": [ + "standards_id", + "records" + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.216Z", + "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 new file mode 100644 index 000000000..3892969f0 --- /dev/null +++ b/schemas/cache/bundled/content-standards/validate-content-delivery-response.json @@ -0,0 +1,193 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Validate Content Delivery Response", + "description": "Response payload with per-record verdicts and optional feature breakdown", + "type": "object", + "oneOf": [ + { + "type": "object", + "description": "Success response", + "properties": { + "summary": { + "type": "object", + "description": "Summary counts across all records", + "properties": { + "total_records": { + "type": "integer" + }, + "passed_records": { + "type": "integer" + }, + "failed_records": { + "type": "integer" + } + }, + "required": [ + "total_records", + "passed_records", + "failed_records" + ] + }, + "results": { + "type": "array", + "description": "Per-record evaluation results", + "items": { + "type": "object", + "properties": { + "record_id": { + "type": "string", + "description": "Which delivery record was evaluated" + }, + "verdict": { + "type": "string", + "enum": [ + "pass", + "fail" + ], + "description": "Overall pass/fail verdict for this record" + }, + "features": { + "type": "array", + "description": "Per-feature breakdown. When present, SHOULD include all failed and warning features. MAY include passed features. Oracle pattern: exposes verdict + rule pointer, never the seller's threshold or the caller's submitted value (the seller authored the content standards).", + "items": { + "type": "object", + "properties": { + "feature_id": { + "type": "string", + "description": "Which feature was evaluated. Data features come from the content-standards feature catalog (e.g., 'brand_safety', 'brand_suitability', 'image_dpi'). Record-level structural checks use reserved namespaces: 'record:malformed_artifact', 'delivery:authorization'. Reserved prefixes: 'record:', 'delivery:'." + }, + "status": { + "type": "string", + "enum": [ + "passed", + "failed", + "warning", + "unevaluated" + ] + }, + "policy_id": { + "type": "string", + "description": "Registry policy ID that triggered this result. Present when the result originates from a specific registry policy (e.g., GARM category, CSBS standard). Enables programmatic routing by looking up the policy in the registry." + }, + "explanation": { + "type": "string", + "description": "Directional human-readable explanation (e.g., 'Below minimum resolution for display placement'). Avoid quantitative thresholds \u2014 the evaluator is the oracle." + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Optional evaluator confidence in this result (0-1). Distinguishes certain verdicts from ambiguous ones." + } + }, + "required": [ + "feature_id", + "status" + ] + } + } + }, + "required": [ + "record_id", + "verdict" + ] + } + }, + "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 + }, + "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": [ + "summary", + "results" + ] + }, + { + "type": "object", + "description": "Error response", + "properties": { + "errors": { + "type": "array", + "items": { + "title": "Error", + "description": "Standard error structure for task-specific errors and warnings", + "type": "object", + "properties": { + "code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification." + }, + "message": { + "type": "string", + "description": "Human-readable error message" + }, + "field": { + "type": "string", + "description": "Field path associated with the error (e.g., 'packages[0].targeting')" + }, + "suggestion": { + "type": "string", + "description": "Suggested fix for the error" + }, + "retry_after": { + "type": "number", + "description": "Seconds to wait before retrying the operation. Sellers MUST return values between 1 and 3600. Clients MUST clamp values outside this range.", + "minimum": 1, + "maximum": 3600 + }, + "details": { + "type": "object", + "description": "Additional task-specific error details", + "additionalProperties": true + }, + "recovery": { + "type": "string", + "enum": [ + "transient", + "correctable", + "terminal" + ], + "description": "Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found)." + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + } + }, + "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 + }, + "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": [ + "errors" + ] + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.217Z", + "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 new file mode 100644 index 000000000..23662b2fe --- /dev/null +++ b/schemas/cache/bundled/core/tasks-get-request.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Tasks Get Request", + "description": "Request parameters for retrieving a specific task by ID with optional conversation history across all AdCP domains", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "task_id": { + "type": "string", + "description": "Unique identifier of the task to retrieve" + }, + "include_history": { + "type": "boolean", + "default": false, + "description": "Include full conversation history for this task (may increase response size)" + }, + "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 + }, + "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": [ + "task_id" + ], + "additionalProperties": true, + "examples": [ + { + "description": "Check task status", + "data": { + "task_id": "task_456" + } + }, + { + "description": "Get task with full conversation history", + "data": { + "task_id": "task_123", + "include_history": true + } + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.219Z", + "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 new file mode 100644 index 000000000..f4951b4cd --- /dev/null +++ b/schemas/cache/bundled/core/tasks-get-response.json @@ -0,0 +1,275 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Tasks Get Response", + "description": "Response containing detailed information about a specific task including status and optional conversation history across all AdCP protocols", + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "Unique identifier for this task" + }, + "task_type": { + "title": "Task Type", + "description": "Type of AdCP operation", + "type": "string", + "enum": [ + "create_media_buy", + "update_media_buy", + "sync_creatives", + "activate_signal", + "get_signals", + "create_property_list", + "update_property_list", + "get_property_list", + "list_property_lists", + "delete_property_list", + "sync_accounts", + "get_account_financials", + "get_creative_delivery", + "sync_event_sources", + "sync_audiences", + "sync_catalogs", + "log_event", + "get_brand_identity", + "get_rights", + "acquire_rights" + ], + "enumDescriptions": { + "create_media_buy": "Media-buy domain: Create a new advertising campaign with one or more packages", + "update_media_buy": "Media-buy domain: Update campaign settings, package configuration, or delivery parameters", + "sync_creatives": "Media-buy domain: Sync creative assets to publisher's library with upsert semantics", + "activate_signal": "Signals domain: Activate an audience signal on a specific platform or account", + "get_signals": "Signals domain: Discover available audience signals based on natural language description", + "create_property_list": "Property domain: Create a new property list with filters and brand reference", + "update_property_list": "Property domain: Update an existing property list", + "get_property_list": "Property domain: Retrieve a property list with resolved properties", + "list_property_lists": "Property domain: List all accessible property lists", + "delete_property_list": "Property domain: Delete a property list", + "sync_accounts": "Account domain: Sync advertiser accounts with a seller using upsert semantics", + "get_account_financials": "Account domain: Query financial status of an operator-billed account (spend, credit, invoices)", + "get_creative_delivery": "Creative domain: Retrieve variant-level creative delivery data", + "sync_event_sources": "Media-buy domain: Configure event sources on an account with upsert semantics", + "sync_audiences": "Media-buy domain: Manage first-party CRM audiences on an account with delta upsert semantics", + "sync_catalogs": "Media-buy domain: Sync catalog feeds (products, inventory, stores, promotions, offerings) to a platform with approval workflow", + "log_event": "Media-buy domain: Send conversion or marketing events for attribution", + "get_brand_identity": "Brand domain: Retrieve brand identity data (logos, colors, tone, assets, voice config) from a brand agent", + "get_rights": "Brand domain: Search for licensable rights across a brand agent's roster with pricing", + "acquire_rights": "Brand domain: Acquire rights from a brand agent with contractual clearance and generation credentials" + }, + "notes": [ + "Task types map to specific AdCP task operations", + "Each task type belongs to the 'media-buy', 'signals', 'property', 'account', 'creative', or 'brand' domain", + "This enum is used in task management APIs (tasks/list, tasks/get) and webhook payloads", + "New task types require a minor version bump per semantic versioning" + ] + }, + "protocol": { + "title": "AdCP Protocol", + "description": "AdCP protocol this task belongs to", + "type": "string", + "enum": [ + "media-buy", + "signals", + "governance", + "creative", + "brand", + "sponsored-intelligence" + ], + "enumDescriptions": { + "media-buy": "Campaign creation, package management, delivery optimization, and conversion tracking", + "signals": "Audience signal discovery and activation", + "governance": "Property governance (identity, authorization, data, selection), brand standards, and compliance", + "creative": "Creative asset management, format discovery, and rendering", + "brand": "Brand identity, rights discovery, and rights acquisition", + "sponsored-intelligence": "AI-mediated commerce and conversational sponsored experiences, including buyer-agent sessions and measurement of AI-surfaced outcomes" + } + }, + "status": { + "title": "Task Status", + "description": "Current task status", + "type": "string", + "enum": [ + "submitted", + "working", + "input-required", + "completed", + "canceled", + "failed", + "rejected", + "auth-required", + "unknown" + ], + "enumDescriptions": { + "submitted": "Task accepted and queued for long-running execution (hours to days). Client should poll with tasks/get or provide webhook_url at protocol level.", + "working": "Agent is actively processing the task, expect completion within 120 seconds", + "input-required": "Task is paused and waiting for input from the user (e.g., clarification, approval)", + "completed": "Task has been successfully completed", + "canceled": "Task was canceled by the user", + "failed": "Task failed due to an error during execution", + "rejected": "Task was rejected by the agent and was not started", + "auth-required": "Task requires authentication to proceed", + "unknown": "Task is in an unknown or indeterminate state" + } + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the task was initially created (ISO 8601)" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "When the task was last updated (ISO 8601)" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "When the task completed (ISO 8601, only for completed/failed/canceled tasks)" + }, + "has_webhook": { + "type": "boolean", + "description": "Whether this task has webhook configuration" + }, + "progress": { + "type": "object", + "description": "Progress information for long-running tasks", + "properties": { + "percentage": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "Completion percentage (0-100)" + }, + "current_step": { + "type": "string", + "description": "Current step or phase of the operation" + }, + "total_steps": { + "type": "integer", + "minimum": 1, + "description": "Total number of steps in the operation" + }, + "step_number": { + "type": "integer", + "minimum": 1, + "description": "Current step number" + } + }, + "additionalProperties": true + }, + "error": { + "type": "object", + "description": "Error details for failed tasks", + "properties": { + "code": { + "type": "string", + "description": "Error code for programmatic handling" + }, + "message": { + "type": "string", + "description": "Detailed error message" + }, + "details": { + "type": "object", + "description": "Additional error context", + "properties": { + "protocol": { + "title": "AdCP Protocol", + "description": "AdCP protocol where error occurred", + "type": "string", + "enum": [ + "media-buy", + "signals", + "governance", + "creative", + "brand", + "sponsored-intelligence" + ], + "enumDescriptions": { + "media-buy": "Campaign creation, package management, delivery optimization, and conversion tracking", + "signals": "Audience signal discovery and activation", + "governance": "Property governance (identity, authorization, data, selection), brand standards, and compliance", + "creative": "Creative asset management, format discovery, and rendering", + "brand": "Brand identity, rights discovery, and rights acquisition", + "sponsored-intelligence": "AI-mediated commerce and conversational sponsored experiences, including buyer-agent sessions and measurement of AI-surfaced outcomes" + } + }, + "operation": { + "type": "string", + "description": "Specific operation that failed" + }, + "specific_context": { + "type": "object", + "description": "Domain-specific error context", + "additionalProperties": true + } + }, + "additionalProperties": true + } + }, + "required": [ + "code", + "message" + ], + "additionalProperties": true + }, + "history": { + "type": "array", + "description": "Complete conversation history for this task (only included if include_history was true in request)", + "items": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "date-time", + "description": "When this exchange occurred (ISO 8601)" + }, + "type": { + "type": "string", + "enum": [ + "request", + "response" + ], + "description": "Whether this was a request from client or response from server" + }, + "data": { + "type": "object", + "description": "The full request or response payload", + "additionalProperties": true + } + }, + "required": [ + "timestamp", + "type", + "data" + ], + "additionalProperties": true + } + }, + "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 + }, + "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": [ + "task_id", + "task_type", + "protocol", + "status", + "created_at", + "updated_at" + ], + "additionalProperties": true, + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.219Z", + "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 new file mode 100644 index 000000000..657353c29 --- /dev/null +++ b/schemas/cache/bundled/core/tasks-list-request.json @@ -0,0 +1,400 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Tasks List Request", + "description": "Request parameters for listing and filtering async tasks across all AdCP protocols with state reconciliation capabilities", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "filters": { + "type": "object", + "description": "Filter criteria for querying tasks", + "properties": { + "protocol": { + "title": "AdCP Protocol", + "description": "Filter by single AdCP protocol", + "type": "string", + "enum": [ + "media-buy", + "signals", + "governance", + "creative", + "brand", + "sponsored-intelligence" + ], + "enumDescriptions": { + "media-buy": "Campaign creation, package management, delivery optimization, and conversion tracking", + "signals": "Audience signal discovery and activation", + "governance": "Property governance (identity, authorization, data, selection), brand standards, and compliance", + "creative": "Creative asset management, format discovery, and rendering", + "brand": "Brand identity, rights discovery, and rights acquisition", + "sponsored-intelligence": "AI-mediated commerce and conversational sponsored experiences, including buyer-agent sessions and measurement of AI-surfaced outcomes" + } + }, + "protocols": { + "type": "array", + "description": "Filter by multiple AdCP protocols", + "items": { + "title": "AdCP Protocol", + "description": "AdCP protocols for task categorization \u2014 referenced by tasks-list-request, webhook payloads, and other task-lifecycle surfaces. Values are kebab-case. This enum shares the same axis as supported_protocols (see /schemas/protocol/get-adcp-capabilities-response.json), which uses snake_case on the wire. Compliance testing support is declared via the `capabilities.compliance_testing` block, not as a protocol value.", + "type": "string", + "enum": [ + "media-buy", + "signals", + "governance", + "creative", + "brand", + "sponsored-intelligence" + ], + "enumDescriptions": { + "media-buy": "Campaign creation, package management, delivery optimization, and conversion tracking", + "signals": "Audience signal discovery and activation", + "governance": "Property governance (identity, authorization, data, selection), brand standards, and compliance", + "creative": "Creative asset management, format discovery, and rendering", + "brand": "Brand identity, rights discovery, and rights acquisition", + "sponsored-intelligence": "AI-mediated commerce and conversational sponsored experiences, including buyer-agent sessions and measurement of AI-surfaced outcomes" + } + }, + "minItems": 1 + }, + "status": { + "title": "Task Status", + "description": "Filter by single task status", + "type": "string", + "enum": [ + "submitted", + "working", + "input-required", + "completed", + "canceled", + "failed", + "rejected", + "auth-required", + "unknown" + ], + "enumDescriptions": { + "submitted": "Task accepted and queued for long-running execution (hours to days). Client should poll with tasks/get or provide webhook_url at protocol level.", + "working": "Agent is actively processing the task, expect completion within 120 seconds", + "input-required": "Task is paused and waiting for input from the user (e.g., clarification, approval)", + "completed": "Task has been successfully completed", + "canceled": "Task was canceled by the user", + "failed": "Task failed due to an error during execution", + "rejected": "Task was rejected by the agent and was not started", + "auth-required": "Task requires authentication to proceed", + "unknown": "Task is in an unknown or indeterminate state" + } + }, + "statuses": { + "type": "array", + "description": "Filter by multiple task statuses", + "items": { + "title": "Task Status", + "description": "Standardized task status values based on A2A TaskState enum. Indicates the current state of any AdCP operation.", + "type": "string", + "enum": [ + "submitted", + "working", + "input-required", + "completed", + "canceled", + "failed", + "rejected", + "auth-required", + "unknown" + ], + "enumDescriptions": { + "submitted": "Task accepted and queued for long-running execution (hours to days). Client should poll with tasks/get or provide webhook_url at protocol level.", + "working": "Agent is actively processing the task, expect completion within 120 seconds", + "input-required": "Task is paused and waiting for input from the user (e.g., clarification, approval)", + "completed": "Task has been successfully completed", + "canceled": "Task was canceled by the user", + "failed": "Task failed due to an error during execution", + "rejected": "Task was rejected by the agent and was not started", + "auth-required": "Task requires authentication to proceed", + "unknown": "Task is in an unknown or indeterminate state" + } + }, + "minItems": 1 + }, + "task_type": { + "title": "Task Type", + "description": "Filter by single task type", + "type": "string", + "enum": [ + "create_media_buy", + "update_media_buy", + "sync_creatives", + "activate_signal", + "get_signals", + "create_property_list", + "update_property_list", + "get_property_list", + "list_property_lists", + "delete_property_list", + "sync_accounts", + "get_account_financials", + "get_creative_delivery", + "sync_event_sources", + "sync_audiences", + "sync_catalogs", + "log_event", + "get_brand_identity", + "get_rights", + "acquire_rights" + ], + "enumDescriptions": { + "create_media_buy": "Media-buy domain: Create a new advertising campaign with one or more packages", + "update_media_buy": "Media-buy domain: Update campaign settings, package configuration, or delivery parameters", + "sync_creatives": "Media-buy domain: Sync creative assets to publisher's library with upsert semantics", + "activate_signal": "Signals domain: Activate an audience signal on a specific platform or account", + "get_signals": "Signals domain: Discover available audience signals based on natural language description", + "create_property_list": "Property domain: Create a new property list with filters and brand reference", + "update_property_list": "Property domain: Update an existing property list", + "get_property_list": "Property domain: Retrieve a property list with resolved properties", + "list_property_lists": "Property domain: List all accessible property lists", + "delete_property_list": "Property domain: Delete a property list", + "sync_accounts": "Account domain: Sync advertiser accounts with a seller using upsert semantics", + "get_account_financials": "Account domain: Query financial status of an operator-billed account (spend, credit, invoices)", + "get_creative_delivery": "Creative domain: Retrieve variant-level creative delivery data", + "sync_event_sources": "Media-buy domain: Configure event sources on an account with upsert semantics", + "sync_audiences": "Media-buy domain: Manage first-party CRM audiences on an account with delta upsert semantics", + "sync_catalogs": "Media-buy domain: Sync catalog feeds (products, inventory, stores, promotions, offerings) to a platform with approval workflow", + "log_event": "Media-buy domain: Send conversion or marketing events for attribution", + "get_brand_identity": "Brand domain: Retrieve brand identity data (logos, colors, tone, assets, voice config) from a brand agent", + "get_rights": "Brand domain: Search for licensable rights across a brand agent's roster with pricing", + "acquire_rights": "Brand domain: Acquire rights from a brand agent with contractual clearance and generation credentials" + }, + "notes": [ + "Task types map to specific AdCP task operations", + "Each task type belongs to the 'media-buy', 'signals', 'property', 'account', 'creative', or 'brand' domain", + "This enum is used in task management APIs (tasks/list, tasks/get) and webhook payloads", + "New task types require a minor version bump per semantic versioning" + ] + }, + "task_types": { + "type": "array", + "description": "Filter by multiple task types", + "items": { + "title": "Task Type", + "description": "Valid AdCP task types across all domains. These represent the complete set of operations that can be tracked via the task management system.", + "type": "string", + "enum": [ + "create_media_buy", + "update_media_buy", + "sync_creatives", + "activate_signal", + "get_signals", + "create_property_list", + "update_property_list", + "get_property_list", + "list_property_lists", + "delete_property_list", + "sync_accounts", + "get_account_financials", + "get_creative_delivery", + "sync_event_sources", + "sync_audiences", + "sync_catalogs", + "log_event", + "get_brand_identity", + "get_rights", + "acquire_rights" + ], + "enumDescriptions": { + "create_media_buy": "Media-buy domain: Create a new advertising campaign with one or more packages", + "update_media_buy": "Media-buy domain: Update campaign settings, package configuration, or delivery parameters", + "sync_creatives": "Media-buy domain: Sync creative assets to publisher's library with upsert semantics", + "activate_signal": "Signals domain: Activate an audience signal on a specific platform or account", + "get_signals": "Signals domain: Discover available audience signals based on natural language description", + "create_property_list": "Property domain: Create a new property list with filters and brand reference", + "update_property_list": "Property domain: Update an existing property list", + "get_property_list": "Property domain: Retrieve a property list with resolved properties", + "list_property_lists": "Property domain: List all accessible property lists", + "delete_property_list": "Property domain: Delete a property list", + "sync_accounts": "Account domain: Sync advertiser accounts with a seller using upsert semantics", + "get_account_financials": "Account domain: Query financial status of an operator-billed account (spend, credit, invoices)", + "get_creative_delivery": "Creative domain: Retrieve variant-level creative delivery data", + "sync_event_sources": "Media-buy domain: Configure event sources on an account with upsert semantics", + "sync_audiences": "Media-buy domain: Manage first-party CRM audiences on an account with delta upsert semantics", + "sync_catalogs": "Media-buy domain: Sync catalog feeds (products, inventory, stores, promotions, offerings) to a platform with approval workflow", + "log_event": "Media-buy domain: Send conversion or marketing events for attribution", + "get_brand_identity": "Brand domain: Retrieve brand identity data (logos, colors, tone, assets, voice config) from a brand agent", + "get_rights": "Brand domain: Search for licensable rights across a brand agent's roster with pricing", + "acquire_rights": "Brand domain: Acquire rights from a brand agent with contractual clearance and generation credentials" + }, + "notes": [ + "Task types map to specific AdCP task operations", + "Each task type belongs to the 'media-buy', 'signals', 'property', 'account', 'creative', or 'brand' domain", + "This enum is used in task management APIs (tasks/list, tasks/get) and webhook payloads", + "New task types require a minor version bump per semantic versioning" + ] + }, + "minItems": 1 + }, + "created_after": { + "type": "string", + "format": "date-time", + "description": "Filter tasks created after this date (ISO 8601)" + }, + "created_before": { + "type": "string", + "format": "date-time", + "description": "Filter tasks created before this date (ISO 8601)" + }, + "updated_after": { + "type": "string", + "format": "date-time", + "description": "Filter tasks last updated after this date (ISO 8601)" + }, + "updated_before": { + "type": "string", + "format": "date-time", + "description": "Filter tasks last updated before this date (ISO 8601)" + }, + "task_ids": { + "type": "array", + "description": "Filter by specific task IDs", + "items": { + "type": "string" + }, + "minItems": 1, + "maxItems": 100 + }, + "context_contains": { + "type": "string", + "description": "Filter tasks where context contains this text (searches media_buy_id, signal_id, etc.)" + }, + "has_webhook": { + "type": "boolean", + "description": "Filter tasks that have webhook configuration when true" + } + }, + "additionalProperties": true + }, + "sort": { + "type": "object", + "description": "Sorting parameters", + "properties": { + "field": { + "type": "string", + "enum": [ + "created_at", + "updated_at", + "status", + "task_type", + "protocol" + ], + "default": "created_at", + "description": "Field to sort by" + }, + "direction": { + "title": "Sort Direction", + "description": "Sort direction", + "type": "string", + "enum": [ + "asc", + "desc" + ], + "default": "desc" + } + }, + "additionalProperties": true + }, + "pagination": { + "title": "Pagination Request", + "description": "Standard cursor-based pagination parameters for list operations", + "type": "object", + "properties": { + "max_results": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50, + "description": "Maximum number of items to return per page" + }, + "cursor": { + "type": "string", + "description": "Opaque cursor from a previous response to fetch the next page" + } + }, + "additionalProperties": false + }, + "include_history": { + "type": "boolean", + "default": false, + "description": "Include full conversation history for each task (may significantly increase response size)" + }, + "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 + }, + "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, + "examples": [ + { + "description": "List all pending tasks across protocols", + "data": { + "filters": { + "statuses": [ + "submitted", + "working", + "input-required" + ] + } + } + }, + { + "description": "Find media-buy tasks requiring attention", + "data": { + "filters": { + "protocol": "media-buy", + "statuses": [ + "input-required", + "failed" + ] + }, + "sort": { + "field": "updated_at", + "direction": "asc" + } + } + }, + { + "description": "Recent signal operations", + "data": { + "filters": { + "protocol": "signals", + "created_after": "2025-01-01T00:00:00Z" + }, + "pagination": { + "max_results": 20 + } + } + }, + { + "description": "State reconciliation for specific campaign", + "data": { + "filters": { + "context_contains": "nike_q1_2025" + }, + "include_history": true + } + } + ], + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.220Z", + "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 new file mode 100644 index 000000000..dead47bf1 --- /dev/null +++ b/schemas/cache/bundled/core/tasks-list-response.json @@ -0,0 +1,256 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Tasks List Response", + "description": "Response from task listing query with filtered results and state reconciliation data across all AdCP domains", + "type": "object", + "properties": { + "query_summary": { + "type": "object", + "description": "Summary of the query that was executed", + "properties": { + "total_matching": { + "type": "integer", + "description": "Total number of tasks matching filters (across all pages)", + "minimum": 0 + }, + "returned": { + "type": "integer", + "description": "Number of tasks returned in this response", + "minimum": 0 + }, + "domain_breakdown": { + "type": "object", + "description": "Count of tasks by domain", + "properties": { + "media-buy": { + "type": "integer", + "minimum": 0, + "description": "Number of media-buy tasks in results" + }, + "signals": { + "type": "integer", + "minimum": 0, + "description": "Number of signals tasks in results" + } + }, + "additionalProperties": true + }, + "status_breakdown": { + "type": "object", + "description": "Count of tasks by status", + "additionalProperties": { + "type": "integer", + "minimum": 0 + } + }, + "filters_applied": { + "type": "array", + "description": "List of filters that were applied to the query", + "items": { + "type": "string" + } + }, + "sort_applied": { + "type": "object", + "description": "Sort order that was applied", + "properties": { + "field": { + "type": "string" + }, + "direction": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + } + }, + "required": [ + "field", + "direction" + ], + "additionalProperties": true + } + }, + "required": [], + "additionalProperties": true + }, + "tasks": { + "type": "array", + "description": "Array of tasks matching the query criteria", + "items": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "Unique identifier for this task" + }, + "task_type": { + "title": "Task Type", + "description": "Type of AdCP operation", + "type": "string", + "enum": [ + "create_media_buy", + "update_media_buy", + "sync_creatives", + "activate_signal", + "get_signals", + "create_property_list", + "update_property_list", + "get_property_list", + "list_property_lists", + "delete_property_list", + "sync_accounts", + "get_account_financials", + "get_creative_delivery", + "sync_event_sources", + "sync_audiences", + "sync_catalogs", + "log_event", + "get_brand_identity", + "get_rights", + "acquire_rights" + ], + "enumDescriptions": { + "create_media_buy": "Media-buy domain: Create a new advertising campaign with one or more packages", + "update_media_buy": "Media-buy domain: Update campaign settings, package configuration, or delivery parameters", + "sync_creatives": "Media-buy domain: Sync creative assets to publisher's library with upsert semantics", + "activate_signal": "Signals domain: Activate an audience signal on a specific platform or account", + "get_signals": "Signals domain: Discover available audience signals based on natural language description", + "create_property_list": "Property domain: Create a new property list with filters and brand reference", + "update_property_list": "Property domain: Update an existing property list", + "get_property_list": "Property domain: Retrieve a property list with resolved properties", + "list_property_lists": "Property domain: List all accessible property lists", + "delete_property_list": "Property domain: Delete a property list", + "sync_accounts": "Account domain: Sync advertiser accounts with a seller using upsert semantics", + "get_account_financials": "Account domain: Query financial status of an operator-billed account (spend, credit, invoices)", + "get_creative_delivery": "Creative domain: Retrieve variant-level creative delivery data", + "sync_event_sources": "Media-buy domain: Configure event sources on an account with upsert semantics", + "sync_audiences": "Media-buy domain: Manage first-party CRM audiences on an account with delta upsert semantics", + "sync_catalogs": "Media-buy domain: Sync catalog feeds (products, inventory, stores, promotions, offerings) to a platform with approval workflow", + "log_event": "Media-buy domain: Send conversion or marketing events for attribution", + "get_brand_identity": "Brand domain: Retrieve brand identity data (logos, colors, tone, assets, voice config) from a brand agent", + "get_rights": "Brand domain: Search for licensable rights across a brand agent's roster with pricing", + "acquire_rights": "Brand domain: Acquire rights from a brand agent with contractual clearance and generation credentials" + }, + "notes": [ + "Task types map to specific AdCP task operations", + "Each task type belongs to the 'media-buy', 'signals', 'property', 'account', 'creative', or 'brand' domain", + "This enum is used in task management APIs (tasks/list, tasks/get) and webhook payloads", + "New task types require a minor version bump per semantic versioning" + ] + }, + "domain": { + "type": "string", + "description": "AdCP domain this task belongs to", + "enum": [ + "media-buy", + "signals" + ] + }, + "status": { + "title": "Task Status", + "description": "Current task status", + "type": "string", + "enum": [ + "submitted", + "working", + "input-required", + "completed", + "canceled", + "failed", + "rejected", + "auth-required", + "unknown" + ], + "enumDescriptions": { + "submitted": "Task accepted and queued for long-running execution (hours to days). Client should poll with tasks/get or provide webhook_url at protocol level.", + "working": "Agent is actively processing the task, expect completion within 120 seconds", + "input-required": "Task is paused and waiting for input from the user (e.g., clarification, approval)", + "completed": "Task has been successfully completed", + "canceled": "Task was canceled by the user", + "failed": "Task failed due to an error during execution", + "rejected": "Task was rejected by the agent and was not started", + "auth-required": "Task requires authentication to proceed", + "unknown": "Task is in an unknown or indeterminate state" + } + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the task was initially created (ISO 8601)" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "When the task was last updated (ISO 8601)" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "When the task completed (ISO 8601, only for completed/failed/canceled tasks)" + }, + "has_webhook": { + "type": "boolean", + "description": "Whether this task has webhook configuration" + } + }, + "required": [ + "task_id", + "task_type", + "domain", + "status", + "created_at", + "updated_at" + ], + "additionalProperties": true + } + }, + "pagination": { + "title": "Pagination Response", + "description": "Standard cursor-based pagination metadata for list responses", + "type": "object", + "properties": { + "has_more": { + "type": "boolean", + "description": "Whether more results are available beyond this page" + }, + "cursor": { + "type": "string", + "description": "Opaque cursor to pass in the next request to fetch the next page. Only present when has_more is true." + }, + "total_count": { + "type": "integer", + "minimum": 0, + "description": "Total number of items matching the query across all pages. Optional because not all backends can efficiently compute this." + } + }, + "required": [ + "has_more" + ], + "additionalProperties": false + }, + "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 + }, + "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": [ + "query_summary", + "tasks", + "pagination" + ], + "additionalProperties": true, + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.221Z", + "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 new file mode 100644 index 000000000..c03ea73ef --- /dev/null +++ b/schemas/cache/bundled/creative/get-creative-delivery-request.json @@ -0,0 +1,198 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Creative Delivery Request", + "description": "Request parameters for retrieving creative delivery data including variant-level metrics from a creative agent. At least one scoping filter (media_buy_ids or creative_ids) is required.", + "type": "object", + "properties": { + "adcp_major_version": { + "type": "integer", + "description": "The AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, + "account": { + "title": "Account Reference", + "description": "Account for routing and scoping. Limits results to creatives within this account.", + "type": "object", + "oneOf": [ + { + "properties": { + "account_id": { + "type": "string", + "description": "Seller-assigned account identifier (from sync_accounts or list_accounts)" + } + }, + "required": [ + "account_id" + ], + "additionalProperties": false + }, + { + "properties": { + "brand": { + "title": "Brand Reference", + "description": "Brand reference identifying the advertiser", + "type": "object", + "properties": { + "domain": { + "type": "string", + "description": "Domain where /.well-known/brand.json is hosted, or the brand's operating domain", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$" + }, + "brand_id": { + "title": "Brand ID", + "description": "Brand identifier within the house portfolio. Optional for single-brand domains.", + "type": "string", + "pattern": "^[a-z0-9_]+$", + "examples": [ + "tide", + "cheerios", + "air_jordan", + "nike", + "pampers" + ] + } + }, + "required": [ + "domain" + ], + "additionalProperties": false, + "examples": [ + { + "domain": "nova-brands.com", + "brand_id": "spark" + }, + { + "domain": "nova-brands.com", + "brand_id": "glow" + }, + { + "domain": "acme-corp.com" + } + ] + }, + "operator": { + "type": "string", + "description": "Domain of the entity operating on the brand's behalf. When the brand operates directly, this is the brand's domain.", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$" + }, + "sandbox": { + "type": "boolean", + "description": "When true, references the sandbox account for this brand/operator pair. Defaults to false (production account).", + "default": false + } + }, + "required": [ + "brand", + "operator" + ], + "additionalProperties": false + } + ], + "examples": [ + { + "account_id": "acc_acme_001" + }, + { + "brand": { + "domain": "acme-corp.com" + }, + "operator": "acme-corp.com" + }, + { + "brand": { + "domain": "nova-brands.com", + "brand_id": "spark" + }, + "operator": "pinnacle-media.com" + }, + { + "brand": { + "domain": "acme-corp.com" + }, + "operator": "acme-corp.com", + "sandbox": true + } + ] + }, + "media_buy_ids": { + "type": "array", + "description": "Filter to specific media buys by publisher ID. If omitted, returns creative delivery across all matching media buys.", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "creative_ids": { + "type": "array", + "description": "Filter to specific creatives by ID. If omitted, returns delivery for all creatives matching the other filters.", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "start_date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "Start date for delivery period (YYYY-MM-DD). Interpreted in the platform's reporting timezone." + }, + "end_date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "End date for delivery period (YYYY-MM-DD). Interpreted in the platform's reporting timezone." + }, + "max_variants": { + "type": "integer", + "description": "Maximum number of variants to return per creative. When omitted, the agent returns all variants. Use this to limit response size for generative creatives that may produce large numbers of variants.", + "minimum": 1 + }, + "pagination": { + "title": "Pagination Request", + "description": "Pagination parameters for the creatives array in the response. Uses cursor-based pagination consistent with other list operations.", + "type": "object", + "properties": { + "max_results": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50, + "description": "Maximum number of items to return per page" + }, + "cursor": { + "type": "string", + "description": "Opaque cursor from a previous response to fetch the next page" + } + }, + "additionalProperties": false + }, + "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 + }, + "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 + } + }, + "anyOf": [ + { + "required": [ + "media_buy_ids" + ] + }, + { + "required": [ + "creative_ids" + ] + } + ], + "additionalProperties": true, + "_bundled": { + "generatedAt": "2026-04-18T19:54:51.221Z", + "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 new file mode 100644 index 000000000..6861b0929 --- /dev/null +++ b/schemas/cache/bundled/creative/get-creative-delivery-response.json @@ -0,0 +1,7379 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Get Creative Delivery Response", + "description": "Response payload for get_creative_delivery task. Returns creative delivery data with variant-level breakdowns including manifests and metrics.", + "type": "object", + "properties": { + "account_id": { + "type": "string", + "description": "Account identifier. Present when the response spans or is scoped to a specific account." + }, + "media_buy_id": { + "type": "string", + "description": "Publisher's media buy identifier. Present when the request was scoped to a single media buy." + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code for monetary values in this response (e.g., 'USD', 'EUR')", + "pattern": "^[A-Z]{3}$" + }, + "reporting_period": { + "type": "object", + "description": "Date range for the report.", + "properties": { + "start": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 start timestamp" + }, + "end": { + "type": "string", + "format": "date-time", + "description": "ISO 8601 end timestamp" + }, + "timezone": { + "type": "string", + "description": "IANA timezone identifier for the reporting period (e.g., 'America/New_York', 'UTC'). Platforms report in their native timezone." + } + }, + "required": [ + "start", + "end" + ], + "additionalProperties": true + }, + "creatives": { + "type": "array", + "description": "Creative delivery data with variant breakdowns", + "items": { + "type": "object", + "properties": { + "creative_id": { + "type": "string", + "description": "Creative identifier" + }, + "media_buy_id": { + "type": "string", + "description": "Publisher's media buy identifier for this creative. Present when the request spanned multiple media buys, so the buyer can correlate each creative to its media buy." + }, + "format_id": { + "title": "Format ID", + "description": "Format of this creative", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "totals": { + "title": "Delivery Metrics", + "description": "Aggregate delivery metrics across all variants of this creative", + "type": "object", + "properties": { + "impressions": { + "type": "number", + "description": "Impressions delivered", + "minimum": 0 + }, + "spend": { + "type": "number", + "description": "Amount spent", + "minimum": 0 + }, + "clicks": { + "type": "number", + "description": "Total clicks", + "minimum": 0 + }, + "ctr": { + "type": "number", + "description": "Click-through rate (clicks/impressions)", + "minimum": 0, + "maximum": 1 + }, + "views": { + "type": "number", + "description": "Content engagements counted toward the billable view threshold. For video this is a platform-defined view event (e.g., 30 seconds or video midpoint); for audio/podcast it is a stream start; for other formats it follows the pricing model's view definition. When the package uses CPV pricing, spend = views \u00d7 rate.", + "minimum": 0 + }, + "completed_views": { + "type": "number", + "description": "Video/audio completions. When the package has a completed_views optimization goal with view_duration_seconds, completions are counted at that threshold rather than 100% completion.", + "minimum": 0 + }, + "completion_rate": { + "type": "number", + "description": "Completion rate (completed_views/impressions)", + "minimum": 0, + "maximum": 1 + }, + "conversions": { + "type": "number", + "description": "Total conversions attributed to this delivery. When by_event_type is present, this equals the sum of all by_event_type[].count entries.", + "minimum": 0 + }, + "conversion_value": { + "type": "number", + "description": "Total monetary value of attributed conversions (in the reporting currency)", + "minimum": 0 + }, + "roas": { + "type": "number", + "description": "Return on ad spend (conversion_value / spend)", + "minimum": 0 + }, + "cost_per_acquisition": { + "type": "number", + "description": "Cost per conversion (spend / conversions)", + "minimum": 0 + }, + "new_to_brand_rate": { + "type": "number", + "description": "Fraction of conversions from first-time brand buyers (0 = none, 1 = all)", + "minimum": 0, + "maximum": 1 + }, + "leads": { + "type": "number", + "description": "Leads generated (convenience alias for by_event_type where event_type='lead')", + "minimum": 0 + }, + "by_event_type": { + "type": "array", + "description": "Conversion metrics broken down by event type. Spend-derived metrics (ROAS, CPA) are only available at the package/totals level since spend cannot be attributed to individual event types.", + "items": { + "type": "object", + "properties": { + "event_type": { + "title": "Event Type", + "description": "The event type", + "type": "string", + "enum": [ + "page_view", + "view_content", + "select_content", + "select_item", + "search", + "share", + "add_to_cart", + "remove_from_cart", + "viewed_cart", + "add_to_wishlist", + "initiate_checkout", + "add_payment_info", + "purchase", + "refund", + "lead", + "qualify_lead", + "close_convert_lead", + "disqualify_lead", + "complete_registration", + "subscribe", + "start_trial", + "app_install", + "app_launch", + "contact", + "schedule", + "donate", + "submit_application", + "custom" + ], + "enumDescriptions": { + "page_view": "User viewed a page", + "view_content": "User viewed specific content (product, article, etc.)", + "select_content": "User selected or clicked on content (article, video, etc.)", + "select_item": "User selected a specific product or item from a list", + "search": "User performed a search", + "share": "User shared content via social or messaging", + "add_to_cart": "User added an item to cart", + "remove_from_cart": "User removed an item from cart", + "viewed_cart": "User viewed their shopping cart", + "add_to_wishlist": "User added an item to a wishlist", + "initiate_checkout": "User started checkout process", + "add_payment_info": "User added payment information", + "purchase": "User completed a purchase", + "refund": "A purchase was fully or partially refunded (adjusts ROAS)", + "lead": "User expressed interest (form submission, signup, etc.)", + "qualify_lead": "Lead qualified by sales or scoring criteria", + "close_convert_lead": "Lead converted to a customer or closed deal", + "disqualify_lead": "Lead disqualified or marked as not viable", + "complete_registration": "User completed account registration", + "subscribe": "User subscribed to a service or newsletter", + "start_trial": "User started a free trial", + "app_install": "User installed an application", + "app_launch": "User launched an application", + "contact": "User initiated contact (call, message, etc.)", + "schedule": "User scheduled an appointment or event", + "donate": "User made a donation", + "submit_application": "User submitted an application (loan, job, etc.)", + "custom": "Custom event type (specify in custom_event_name)" + } + }, + "event_source_id": { + "type": "string", + "description": "Event source that produced these conversions (for disambiguation when multiple event sources are configured)" + }, + "count": { + "type": "number", + "description": "Number of events of this type", + "minimum": 0 + }, + "value": { + "type": "number", + "description": "Total monetary value of events of this type", + "minimum": 0 + } + }, + "required": [ + "event_type", + "count" + ], + "additionalProperties": true + } + }, + "grps": { + "type": "number", + "description": "Gross Rating Points delivered (for CPP)", + "minimum": 0 + }, + "reach": { + "type": "number", + "description": "Unique reach in the units specified by reach_unit. When reach_unit is omitted, units are unspecified \u2014 do not compare reach values across packages or media buys without a common reach_unit.", + "minimum": 0 + }, + "reach_unit": { + "allOf": [ + { + "title": "Reach Unit", + "description": "Unit of measurement for reach and audience size metrics. Different channels and measurement providers count reach in fundamentally different units, making cross-channel comparison impossible without declaring the unit.", + "type": "string", + "enum": [ + "individuals", + "households", + "devices", + "accounts", + "cookies", + "custom" + ], + "enumDescriptions": { + "individuals": "Unique people. Panel-based or identity-resolved measurement.", + "households": "Unique households or TV homes.", + "devices": "Unique device identifiers (IDFA, GAID, CTV device ID).", + "accounts": "Unique logged-in accounts (platform-specific identity).", + "cookies": "Unique browser cookies.", + "custom": "Publisher-defined reach unit. Describe in ext." + } + } + ], + "description": "Unit of measurement for the reach field. Aligns with the reach_unit declared on optimization goals and delivery forecasts. Required when reach is present to enable cross-platform comparison." + }, + "frequency": { + "type": "number", + "description": "Average frequency per reach unit (typically measured over campaign duration, but can vary by measurement provider). When reach_unit is 'households', this is average exposures per household; when 'accounts', per logged-in account; etc.", + "minimum": 0 + }, + "quartile_data": { + "type": "object", + "description": "Audio/video quartile completion data", + "properties": { + "q1_views": { + "type": "number", + "description": "25% completion views", + "minimum": 0 + }, + "q2_views": { + "type": "number", + "description": "50% completion views", + "minimum": 0 + }, + "q3_views": { + "type": "number", + "description": "75% completion views", + "minimum": 0 + }, + "q4_views": { + "type": "number", + "description": "100% completion views", + "minimum": 0 + } + } + }, + "dooh_metrics": { + "type": "object", + "description": "DOOH-specific metrics (only included for DOOH campaigns)", + "properties": { + "loop_plays": { + "type": "integer", + "description": "Number of times ad played in rotation", + "minimum": 0 + }, + "screens_used": { + "type": "integer", + "description": "Number of unique screens displaying the ad", + "minimum": 0 + }, + "screen_time_seconds": { + "type": "integer", + "description": "Total display time in seconds", + "minimum": 0 + }, + "sov_achieved": { + "type": "number", + "description": "Actual share of voice delivered (0.0 to 1.0)", + "minimum": 0, + "maximum": 1 + }, + "calculation_notes": { + "type": "string", + "description": "Explanation of how DOOH impressions were calculated" + }, + "venue_breakdown": { + "type": "array", + "description": "Per-venue performance breakdown", + "items": { + "type": "object", + "properties": { + "venue_id": { + "type": "string", + "description": "Venue identifier" + }, + "venue_name": { + "type": "string", + "description": "Human-readable venue name" + }, + "venue_type": { + "type": "string", + "description": "Venue type (e.g., 'airport', 'transit', 'retail', 'billboard')" + }, + "impressions": { + "type": "integer", + "description": "Impressions delivered at this venue", + "minimum": 0 + }, + "loop_plays": { + "type": "integer", + "description": "Loop plays at this venue", + "minimum": 0 + }, + "screens_used": { + "type": "integer", + "description": "Number of screens used at this venue", + "minimum": 0 + } + }, + "required": [ + "venue_id", + "impressions" + ], + "additionalProperties": true + } + } + }, + "additionalProperties": true + }, + "viewability": { + "type": "object", + "description": "Viewability metrics. Viewable rate should be calculated as viewable_impressions / measurable_impressions (not total impressions), since some environments cannot measure viewability.", + "properties": { + "measurable_impressions": { + "type": "number", + "description": "Impressions where viewability could be measured. Excludes environments without measurement capability (e.g., non-Intersection Observer browsers, certain app environments).", + "minimum": 0 + }, + "viewable_impressions": { + "type": "number", + "description": "Impressions that met the viewability threshold defined by the measurement standard.", + "minimum": 0 + }, + "viewable_rate": { + "type": "number", + "description": "Viewable impression rate (viewable_impressions / measurable_impressions). Range 0.0 to 1.0.", + "minimum": 0, + "maximum": 1 + }, + "standard": { + "title": "Viewability Standard", + "description": "Viewability measurement standard applied to these metrics.", + "type": "string", + "enum": [ + "mrc", + "groupm" + ], + "enumDescriptions": { + "mrc": "MRC/IAB standard: 50% of pixels in view for 1 continuous second (display) or 2 continuous seconds (video).", + "groupm": "GroupM standard: 100% of pixels in view for 1 continuous second (display) or 50% of video duration." + } + } + }, + "additionalProperties": true + }, + "engagements": { + "type": "number", + "description": "Total engagements \u2014 direct interactions with the ad beyond viewing. Includes social reactions/comments/shares, story/unit opens, interactive overlay taps on CTV, companion banner interactions on audio. Platform-specific; corresponds to the 'engagements' optimization metric.", + "minimum": 0 + }, + "follows": { + "type": "number", + "description": "New followers, page likes, artist/podcast/channel subscribes attributed to this delivery.", + "minimum": 0 + }, + "saves": { + "type": "number", + "description": "Saves, bookmarks, playlist adds, pins attributed to this delivery.", + "minimum": 0 + }, + "profile_visits": { + "type": "number", + "description": "Visits to the brand's in-platform page (profile, artist page, channel, or storefront) attributed to this delivery. Does not include external website clicks.", + "minimum": 0 + }, + "engagement_rate": { + "type": "number", + "description": "Platform-specific engagement rate (0.0 to 1.0). Typically engagements/impressions, but definition varies by platform.", + "minimum": 0, + "maximum": 1 + }, + "cost_per_click": { + "type": "number", + "description": "Cost per click (spend / clicks)", + "minimum": 0 + }, + "by_action_source": { + "type": "array", + "description": "Conversion metrics broken down by action source (website, app, in_store, etc.). Useful for omnichannel sellers where conversions occur across digital and physical channels.", + "items": { + "type": "object", + "properties": { + "action_source": { + "title": "Action Source", + "description": "Where the conversion occurred", + "type": "string", + "enum": [ + "website", + "app", + "offline", + "phone_call", + "chat", + "email", + "in_store", + "system_generated", + "other" + ], + "enumDescriptions": { + "website": "Event occurred on a website", + "app": "Event occurred in a mobile or desktop app", + "offline": "Event occurred offline (imported data)", + "phone_call": "Event originated from a phone call", + "chat": "Event originated from a chat conversation", + "email": "Event originated from an email interaction", + "in_store": "Event occurred at a physical retail location", + "system_generated": "Event generated by an automated system", + "other": "Other source (specify in ext)" + } + }, + "event_source_id": { + "type": "string", + "description": "Event source that produced these conversions (for disambiguation when multiple event sources are configured)" + }, + "count": { + "type": "number", + "description": "Number of conversions from this action source", + "minimum": 0 + }, + "value": { + "type": "number", + "description": "Total monetary value of conversions from this action source", + "minimum": 0 + } + }, + "required": [ + "action_source", + "count" + ], + "additionalProperties": true + } + } + }, + "dependencies": { + "reach": [ + "reach_unit" + ] + }, + "additionalProperties": true + }, + "variant_count": { + "type": "integer", + "description": "Total number of variants for this creative. When max_variants was specified in the request, this may exceed the number of items in the variants array.", + "minimum": 0 + }, + "variants": { + "type": "array", + "description": "Variant-level delivery breakdown. Each variant includes the rendered manifest and delivery metrics. For standard creatives, contains a single variant. For asset group optimization, one per combination. For generative creative, one per generated execution. Empty when a creative has no variants yet.", + "items": { + "title": "Creative Variant", + "description": "A specific execution variant of a creative with delivery metrics. For catalog-driven packages, each catalog item rendered as a distinct ad execution is a variant \u2014 the variant's manifest includes the catalog reference with the specific item rendered. For asset group optimization, represents one combination of assets the platform selected. For generative creative, represents a platform-generated variant. For standard creatives, maps 1:1 with the creative itself.", + "type": "object", + "allOf": [ + { + "title": "Delivery Metrics", + "description": "Standard delivery metrics that can be reported at media buy, package, or creative level", + "type": "object", + "properties": { + "impressions": { + "type": "number", + "description": "Impressions delivered", + "minimum": 0 + }, + "spend": { + "type": "number", + "description": "Amount spent", + "minimum": 0 + }, + "clicks": { + "type": "number", + "description": "Total clicks", + "minimum": 0 + }, + "ctr": { + "type": "number", + "description": "Click-through rate (clicks/impressions)", + "minimum": 0, + "maximum": 1 + }, + "views": { + "type": "number", + "description": "Content engagements counted toward the billable view threshold. For video this is a platform-defined view event (e.g., 30 seconds or video midpoint); for audio/podcast it is a stream start; for other formats it follows the pricing model's view definition. When the package uses CPV pricing, spend = views \u00d7 rate.", + "minimum": 0 + }, + "completed_views": { + "type": "number", + "description": "Video/audio completions. When the package has a completed_views optimization goal with view_duration_seconds, completions are counted at that threshold rather than 100% completion.", + "minimum": 0 + }, + "completion_rate": { + "type": "number", + "description": "Completion rate (completed_views/impressions)", + "minimum": 0, + "maximum": 1 + }, + "conversions": { + "type": "number", + "description": "Total conversions attributed to this delivery. When by_event_type is present, this equals the sum of all by_event_type[].count entries.", + "minimum": 0 + }, + "conversion_value": { + "type": "number", + "description": "Total monetary value of attributed conversions (in the reporting currency)", + "minimum": 0 + }, + "roas": { + "type": "number", + "description": "Return on ad spend (conversion_value / spend)", + "minimum": 0 + }, + "cost_per_acquisition": { + "type": "number", + "description": "Cost per conversion (spend / conversions)", + "minimum": 0 + }, + "new_to_brand_rate": { + "type": "number", + "description": "Fraction of conversions from first-time brand buyers (0 = none, 1 = all)", + "minimum": 0, + "maximum": 1 + }, + "leads": { + "type": "number", + "description": "Leads generated (convenience alias for by_event_type where event_type='lead')", + "minimum": 0 + }, + "by_event_type": { + "type": "array", + "description": "Conversion metrics broken down by event type. Spend-derived metrics (ROAS, CPA) are only available at the package/totals level since spend cannot be attributed to individual event types.", + "items": { + "type": "object", + "properties": { + "event_type": { + "title": "Event Type", + "description": "The event type", + "type": "string", + "enum": [ + "page_view", + "view_content", + "select_content", + "select_item", + "search", + "share", + "add_to_cart", + "remove_from_cart", + "viewed_cart", + "add_to_wishlist", + "initiate_checkout", + "add_payment_info", + "purchase", + "refund", + "lead", + "qualify_lead", + "close_convert_lead", + "disqualify_lead", + "complete_registration", + "subscribe", + "start_trial", + "app_install", + "app_launch", + "contact", + "schedule", + "donate", + "submit_application", + "custom" + ], + "enumDescriptions": { + "page_view": "User viewed a page", + "view_content": "User viewed specific content (product, article, etc.)", + "select_content": "User selected or clicked on content (article, video, etc.)", + "select_item": "User selected a specific product or item from a list", + "search": "User performed a search", + "share": "User shared content via social or messaging", + "add_to_cart": "User added an item to cart", + "remove_from_cart": "User removed an item from cart", + "viewed_cart": "User viewed their shopping cart", + "add_to_wishlist": "User added an item to a wishlist", + "initiate_checkout": "User started checkout process", + "add_payment_info": "User added payment information", + "purchase": "User completed a purchase", + "refund": "A purchase was fully or partially refunded (adjusts ROAS)", + "lead": "User expressed interest (form submission, signup, etc.)", + "qualify_lead": "Lead qualified by sales or scoring criteria", + "close_convert_lead": "Lead converted to a customer or closed deal", + "disqualify_lead": "Lead disqualified or marked as not viable", + "complete_registration": "User completed account registration", + "subscribe": "User subscribed to a service or newsletter", + "start_trial": "User started a free trial", + "app_install": "User installed an application", + "app_launch": "User launched an application", + "contact": "User initiated contact (call, message, etc.)", + "schedule": "User scheduled an appointment or event", + "donate": "User made a donation", + "submit_application": "User submitted an application (loan, job, etc.)", + "custom": "Custom event type (specify in custom_event_name)" + } + }, + "event_source_id": { + "type": "string", + "description": "Event source that produced these conversions (for disambiguation when multiple event sources are configured)" + }, + "count": { + "type": "number", + "description": "Number of events of this type", + "minimum": 0 + }, + "value": { + "type": "number", + "description": "Total monetary value of events of this type", + "minimum": 0 + } + }, + "required": [ + "event_type", + "count" + ], + "additionalProperties": true + } + }, + "grps": { + "type": "number", + "description": "Gross Rating Points delivered (for CPP)", + "minimum": 0 + }, + "reach": { + "type": "number", + "description": "Unique reach in the units specified by reach_unit. When reach_unit is omitted, units are unspecified \u2014 do not compare reach values across packages or media buys without a common reach_unit.", + "minimum": 0 + }, + "reach_unit": { + "allOf": [ + { + "title": "Reach Unit", + "description": "Unit of measurement for reach and audience size metrics. Different channels and measurement providers count reach in fundamentally different units, making cross-channel comparison impossible without declaring the unit.", + "type": "string", + "enum": [ + "individuals", + "households", + "devices", + "accounts", + "cookies", + "custom" + ], + "enumDescriptions": { + "individuals": "Unique people. Panel-based or identity-resolved measurement.", + "households": "Unique households or TV homes.", + "devices": "Unique device identifiers (IDFA, GAID, CTV device ID).", + "accounts": "Unique logged-in accounts (platform-specific identity).", + "cookies": "Unique browser cookies.", + "custom": "Publisher-defined reach unit. Describe in ext." + } + } + ], + "description": "Unit of measurement for the reach field. Aligns with the reach_unit declared on optimization goals and delivery forecasts. Required when reach is present to enable cross-platform comparison." + }, + "frequency": { + "type": "number", + "description": "Average frequency per reach unit (typically measured over campaign duration, but can vary by measurement provider). When reach_unit is 'households', this is average exposures per household; when 'accounts', per logged-in account; etc.", + "minimum": 0 + }, + "quartile_data": { + "type": "object", + "description": "Audio/video quartile completion data", + "properties": { + "q1_views": { + "type": "number", + "description": "25% completion views", + "minimum": 0 + }, + "q2_views": { + "type": "number", + "description": "50% completion views", + "minimum": 0 + }, + "q3_views": { + "type": "number", + "description": "75% completion views", + "minimum": 0 + }, + "q4_views": { + "type": "number", + "description": "100% completion views", + "minimum": 0 + } + } + }, + "dooh_metrics": { + "type": "object", + "description": "DOOH-specific metrics (only included for DOOH campaigns)", + "properties": { + "loop_plays": { + "type": "integer", + "description": "Number of times ad played in rotation", + "minimum": 0 + }, + "screens_used": { + "type": "integer", + "description": "Number of unique screens displaying the ad", + "minimum": 0 + }, + "screen_time_seconds": { + "type": "integer", + "description": "Total display time in seconds", + "minimum": 0 + }, + "sov_achieved": { + "type": "number", + "description": "Actual share of voice delivered (0.0 to 1.0)", + "minimum": 0, + "maximum": 1 + }, + "calculation_notes": { + "type": "string", + "description": "Explanation of how DOOH impressions were calculated" + }, + "venue_breakdown": { + "type": "array", + "description": "Per-venue performance breakdown", + "items": { + "type": "object", + "properties": { + "venue_id": { + "type": "string", + "description": "Venue identifier" + }, + "venue_name": { + "type": "string", + "description": "Human-readable venue name" + }, + "venue_type": { + "type": "string", + "description": "Venue type (e.g., 'airport', 'transit', 'retail', 'billboard')" + }, + "impressions": { + "type": "integer", + "description": "Impressions delivered at this venue", + "minimum": 0 + }, + "loop_plays": { + "type": "integer", + "description": "Loop plays at this venue", + "minimum": 0 + }, + "screens_used": { + "type": "integer", + "description": "Number of screens used at this venue", + "minimum": 0 + } + }, + "required": [ + "venue_id", + "impressions" + ], + "additionalProperties": true + } + } + }, + "additionalProperties": true + }, + "viewability": { + "type": "object", + "description": "Viewability metrics. Viewable rate should be calculated as viewable_impressions / measurable_impressions (not total impressions), since some environments cannot measure viewability.", + "properties": { + "measurable_impressions": { + "type": "number", + "description": "Impressions where viewability could be measured. Excludes environments without measurement capability (e.g., non-Intersection Observer browsers, certain app environments).", + "minimum": 0 + }, + "viewable_impressions": { + "type": "number", + "description": "Impressions that met the viewability threshold defined by the measurement standard.", + "minimum": 0 + }, + "viewable_rate": { + "type": "number", + "description": "Viewable impression rate (viewable_impressions / measurable_impressions). Range 0.0 to 1.0.", + "minimum": 0, + "maximum": 1 + }, + "standard": { + "title": "Viewability Standard", + "description": "Viewability measurement standard applied to these metrics.", + "type": "string", + "enum": [ + "mrc", + "groupm" + ], + "enumDescriptions": { + "mrc": "MRC/IAB standard: 50% of pixels in view for 1 continuous second (display) or 2 continuous seconds (video).", + "groupm": "GroupM standard: 100% of pixels in view for 1 continuous second (display) or 50% of video duration." + } + } + }, + "additionalProperties": true + }, + "engagements": { + "type": "number", + "description": "Total engagements \u2014 direct interactions with the ad beyond viewing. Includes social reactions/comments/shares, story/unit opens, interactive overlay taps on CTV, companion banner interactions on audio. Platform-specific; corresponds to the 'engagements' optimization metric.", + "minimum": 0 + }, + "follows": { + "type": "number", + "description": "New followers, page likes, artist/podcast/channel subscribes attributed to this delivery.", + "minimum": 0 + }, + "saves": { + "type": "number", + "description": "Saves, bookmarks, playlist adds, pins attributed to this delivery.", + "minimum": 0 + }, + "profile_visits": { + "type": "number", + "description": "Visits to the brand's in-platform page (profile, artist page, channel, or storefront) attributed to this delivery. Does not include external website clicks.", + "minimum": 0 + }, + "engagement_rate": { + "type": "number", + "description": "Platform-specific engagement rate (0.0 to 1.0). Typically engagements/impressions, but definition varies by platform.", + "minimum": 0, + "maximum": 1 + }, + "cost_per_click": { + "type": "number", + "description": "Cost per click (spend / clicks)", + "minimum": 0 + }, + "by_action_source": { + "type": "array", + "description": "Conversion metrics broken down by action source (website, app, in_store, etc.). Useful for omnichannel sellers where conversions occur across digital and physical channels.", + "items": { + "type": "object", + "properties": { + "action_source": { + "title": "Action Source", + "description": "Where the conversion occurred", + "type": "string", + "enum": [ + "website", + "app", + "offline", + "phone_call", + "chat", + "email", + "in_store", + "system_generated", + "other" + ], + "enumDescriptions": { + "website": "Event occurred on a website", + "app": "Event occurred in a mobile or desktop app", + "offline": "Event occurred offline (imported data)", + "phone_call": "Event originated from a phone call", + "chat": "Event originated from a chat conversation", + "email": "Event originated from an email interaction", + "in_store": "Event occurred at a physical retail location", + "system_generated": "Event generated by an automated system", + "other": "Other source (specify in ext)" + } + }, + "event_source_id": { + "type": "string", + "description": "Event source that produced these conversions (for disambiguation when multiple event sources are configured)" + }, + "count": { + "type": "number", + "description": "Number of conversions from this action source", + "minimum": 0 + }, + "value": { + "type": "number", + "description": "Total monetary value of conversions from this action source", + "minimum": 0 + } + }, + "required": [ + "action_source", + "count" + ], + "additionalProperties": true + } + } + }, + "dependencies": { + "reach": [ + "reach_unit" + ] + }, + "additionalProperties": true + }, + { + "properties": { + "variant_id": { + "type": "string", + "description": "Platform-assigned identifier for this variant" + }, + "manifest": { + "title": "Creative Manifest", + "description": "The rendered creative manifest for this variant \u2014 the actual output that was served, not the input assets. Contains format_id and the resolved assets (specific headline, image, video, etc. the platform selected or generated). For Tier 2, shows which asset combination was picked. For Tier 3, contains the generated assets which may differ entirely from the input brand identity. Pass to preview_creative to re-render.", + "type": "object", + "properties": { + "format_id": { + "title": "Format ID", + "description": "Format identifier this manifest is for. Can be a template format (id only) or a deterministic format (id + dimensions/duration). For dimension-specific creatives, include width/height/unit in the format_id to create a unique identifier (e.g., {id: 'display_static', width: 300, height: 250, unit: 'px'}).", + "type": "object", + "properties": { + "agent_url": { + "type": "string", + "format": "uri", + "description": "URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)" + }, + "id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "duration_ms": { + "type": "number", + "minimum": 1, + "description": "Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters." + } + }, + "required": [ + "agent_url", + "id" + ], + "additionalProperties": true, + "dependencies": { + "width": [ + "height" + ], + "height": [ + "width" + ] + } + }, + "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.", + "patternProperties": { + "^[a-z0-9_]+$": { + "anyOf": [ + { + "title": "Image Asset", + "description": "Image asset with URL and dimensions", + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "URL to the image asset" + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels" + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels" + }, + "format": { + "type": "string", + "description": "Image file format (jpg, png, gif, webp, etc.)" + }, + "alt_text": { + "type": "string", + "description": "Alternative text for accessibility", + "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": [ + "url", + "width", + "height" + ], + "additionalProperties": true + }, + { + "title": "Video Asset", + "description": "Video asset with URL and technical specifications including audio track properties", + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "URL to the video asset" + }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels" + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels" + }, + "duration_ms": { + "type": "integer", + "description": "Video duration in milliseconds", + "minimum": 1 + }, + "file_size_bytes": { + "type": "integer", + "description": "File size in bytes", + "minimum": 1 + }, + "container_format": { + "type": "string", + "description": "Video container format (mp4, webm, mov, etc.)" + }, + "video_codec": { + "type": "string", + "description": "Video codec used (h264, h265, vp9, av1, prores, etc.)" + }, + "video_bitrate_kbps": { + "type": "integer", + "description": "Video stream bitrate in kilobits per second", + "minimum": 1 + }, + "frame_rate": { + "type": "string", + "description": "Frame rate as string to preserve precision (e.g., '23.976', '29.97', '30')" + }, + "frame_rate_type": { + "type": "string", + "enum": [ + "constant", + "variable" + ], + "description": "Whether the video uses constant (CFR) or variable (VFR) frame rate" + }, + "scan_type": { + "type": "string", + "enum": [ + "progressive", + "interlaced" + ], + "description": "Scan type of the video" + }, + "color_space": { + "type": "string", + "enum": [ + "rec709", + "rec2020", + "rec2100", + "srgb", + "dci_p3" + ], + "description": "Color space of the video" + }, + "hdr_format": { + "type": "string", + "enum": [ + "sdr", + "hdr10", + "hdr10_plus", + "hlg", + "dolby_vision" + ], + "description": "HDR format if applicable, or 'sdr' for standard dynamic range" + }, + "chroma_subsampling": { + "type": "string", + "enum": [ + "4:2:0", + "4:2:2", + "4:4:4" + ], + "description": "Chroma subsampling format" + }, + "video_bit_depth": { + "type": "integer", + "enum": [ + 8, + 10, + 12 + ], + "description": "Video bit depth" + }, + "gop_interval_seconds": { + "type": "number", + "description": "GOP/keyframe interval in seconds" + }, + "gop_type": { + "type": "string", + "enum": [ + "closed", + "open" + ], + "description": "GOP structure type" + }, + "moov_atom_position": { + "type": "string", + "enum": [ + "start", + "end" + ], + "description": "Position of moov atom in MP4 container" + }, + "has_audio": { + "type": "boolean", + "description": "Whether the video contains an audio track" + }, + "audio_codec": { + "type": "string", + "description": "Audio codec used (aac, aac_lc, he_aac, pcm, mp3, ac3, eac3, etc.)" + }, + "audio_sampling_rate_hz": { + "type": "integer", + "description": "Audio sampling rate in Hz (e.g., 44100, 48000)" + }, + "audio_channels": { + "type": "string", + "enum": [ + "mono", + "stereo", + "5.1", + "7.1" + ], + "description": "Audio channel configuration" + }, + "audio_bit_depth": { + "type": "integer", + "enum": [ + 16, + 24, + 32 + ], + "description": "Audio bit depth" + }, + "audio_bitrate_kbps": { + "type": "integer", + "description": "Audio bitrate in kilobits per second", + "minimum": 1 + }, + "audio_loudness_lufs": { + "type": "number", + "description": "Integrated loudness in LUFS" + }, + "audio_true_peak_dbfs": { + "type": "number", + "description": "True peak level in dBFS" + }, + "captions_url": { + "type": "string", + "format": "uri", + "description": "URL to captions file (WebVTT, SRT, etc.)", + "x-accessibility": true + }, + "transcript_url": { + "type": "string", + "format": "uri", + "description": "URL to text transcript of the video content", + "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": { + "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": [ + "url", + "width", + "height" + ], + "additionalProperties": true + }, + { + "title": "Audio Asset", + "description": "Audio asset with URL and technical specifications", + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "URL to the audio asset" + }, + "duration_ms": { + "type": "integer", + "description": "Audio duration in milliseconds", + "minimum": 0 + }, + "file_size_bytes": { + "type": "integer", + "description": "File size in bytes", + "minimum": 1 + }, + "container_format": { + "type": "string", + "description": "Audio container/file format (mp3, m4a, aac, wav, ogg, flac, etc.)" + }, + "codec": { + "type": "string", + "description": "Audio codec used (aac, aac_lc, he_aac, pcm, mp3, vorbis, opus, flac, ac3, eac3, etc.)" + }, + "sampling_rate_hz": { + "type": "integer", + "description": "Sampling rate in Hz (e.g., 44100, 48000, 96000)" + }, + "channels": { + "type": "string", + "enum": [ + "mono", + "stereo", + "5.1", + "7.1" + ], + "description": "Channel configuration" + }, + "bit_depth": { + "type": "integer", + "enum": [ + 16, + 24, + 32 + ], + "description": "Bit depth" + }, + "bitrate_kbps": { + "type": "integer", + "description": "Bitrate in kilobits per second", + "minimum": 1 + }, + "loudness_lufs": { + "type": "number", + "description": "Integrated loudness in LUFS" + }, + "true_peak_dbfs": { + "type": "number", + "description": "True peak level in dBFS" + }, + "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": [ + "url" + ], + "additionalProperties": true + }, + { + "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": "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": { + "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", + "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": { + "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": { + "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": [ + "content" + ], + "additionalProperties": true + }, + { + "title": "URL Asset", + "description": "URL reference asset", + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "URL reference" + }, + "url_type": { + "title": "URL Asset Type", + "description": "Type of URL asset: 'clickthrough' for user click destination (landing page), 'tracker_pixel' for impression/event tracking via HTTP request (fires GET, expects pixel/204 response), 'tracker_script' for measurement SDKs that must load as