From 6d4afa6cd06cd9de1889c9d18d5f7acc34406d36 Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Thu, 16 Oct 2025 21:49:08 -0400 Subject: [PATCH 1/3] Fix format_id structure: convert strings to structured objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated all documentation to match schema definition where format_id is always a structured object with agent_url and id fields, not a plain string. Changes: - Converted 114 occurrences across 17 documentation files - format_id now consistently uses {"agent_url": "...", "id": "..."} - Removes parsing ambiguity and namespace collision issues - Aligns with /schemas/v1/core/format-id.json specification Files updated: - docs/creative/* (14 files) - docs/media-buy/* (3 files) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/creative/asset-types.md | 10 ++- docs/creative/brand-manifest.md | 5 +- docs/creative/channels/audio.md | 35 ++++++-- docs/creative/channels/carousels.md | 45 ++++++++--- docs/creative/channels/display.md | 80 +++++++++++++++---- docs/creative/channels/dooh.md | 25 ++++-- docs/creative/channels/video.md | 65 ++++++++++++--- docs/creative/creative-manifests.md | 40 ++++++++-- docs/creative/formats.md | 28 +++++-- docs/creative/generative-creative.md | 38 ++++++--- docs/creative/implementing-creative-agents.md | 24 ++++-- .../task-reference/list_creative_formats.md | 15 +++- .../task-reference/preview_creative.md | 55 ++++++++++--- docs/creative/universal-macros.md | 20 ++++- .../implementing-standard-formats.md | 66 +++++++++++---- docs/media-buy/task-reference/get_products.md | 2 +- .../task-reference/list_creative_formats.md | 75 +++++++++++++---- 17 files changed, 491 insertions(+), 137 deletions(-) diff --git a/docs/creative/asset-types.md b/docs/creative/asset-types.md index 134aa4588..71af4b248 100644 --- a/docs/creative/asset-types.md +++ b/docs/creative/asset-types.md @@ -263,7 +263,10 @@ When submitting creative assets, the orchestrator uses `asset_id` to map files: ```json { - "format_id": "foundational_immersive_canvas", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "foundational_immersive_canvas" + }, "assets": { "hero_image": "https://cdn.example.com/campaign123/hero.jpg", "brand_logo": "https://cdn.example.com/brand/logo.png", @@ -282,7 +285,10 @@ Creative formats specify their required assets using these standardized types: ```json { - "format_id": "video_15s_hosted", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_15s_hosted" + }, "assets": [ { "asset_id": "video_file", diff --git a/docs/creative/brand-manifest.md b/docs/creative/brand-manifest.md index c808ac43b..826159a32 100644 --- a/docs/creative/brand-manifest.md +++ b/docs/creative/brand-manifest.md @@ -306,7 +306,10 @@ Use brand manifest to inform creative generation: ```json { "message": "Create a native ad highlighting our new product launch", - "format_id": "display_native", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_native" + }, "brand_manifest": { "url": "https://acmecorp.com", "logos": [ diff --git a/docs/creative/channels/audio.md b/docs/creative/channels/audio.md index 6a6e81b45..9169c1a69 100644 --- a/docs/creative/channels/audio.md +++ b/docs/creative/channels/audio.md @@ -22,7 +22,10 @@ Audio ads are typically non-skippable and play during natural content breaks. ```json { - "format_id": "audio_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_30s" + }, "type": "audio", "assets_required": [ { @@ -45,7 +48,10 @@ Audio ads are typically non-skippable and play during natural content breaks. ```json { - "format_id": "audio_30s_companion", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_30s_companion" + }, "type": "audio", "assets_required": [ { @@ -79,7 +85,10 @@ Audio ads are typically non-skippable and play during natural content breaks. ```json { - "format_id": "podcast_midroll_60s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "podcast_midroll_60s" + }, "type": "audio", "assets_required": [ { @@ -104,7 +113,10 @@ Multi-segment audio assembled dynamically: ```json { - "format_id": "audio_dynamic_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_dynamic_30s" + }, "type": "audio", "assets_required": [ { @@ -150,7 +162,10 @@ Multi-segment audio assembled dynamically: ```json { - "format_id": "audio_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_30s" + }, "assets": { "audio_file": { "asset_type": "audio", @@ -176,7 +191,10 @@ Multi-segment audio assembled dynamically: ```json { - "format_id": "audio_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_30s_vast" + }, "assets": { "vast_url": { "asset_type": "url", @@ -191,7 +209,10 @@ Multi-segment audio assembled dynamically: ```json { - "format_id": "audio_30s_companion", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_30s_companion" + }, "assets": { "audio_file": { "asset_type": "audio", diff --git a/docs/creative/channels/carousels.md b/docs/creative/channels/carousels.md index ed82e32b6..a3ab07774 100644 --- a/docs/creative/channels/carousels.md +++ b/docs/creative/channels/carousels.md @@ -24,7 +24,10 @@ Carousel formats define a repeatable asset group containing the assets for each ```json { - "format_id": "product_carousel_3_to_10", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "product_carousel_3_to_10" + }, "type": "display", "dimensions": "300x250", "assets_required": [ @@ -71,7 +74,10 @@ Carousel formats define a repeatable asset group containing the assets for each ```json { - "format_id": "product_carousel_display", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "product_carousel_display" + }, "type": "display", "dimensions": "300x600", "assets_required": [ @@ -112,7 +118,10 @@ Carousel formats define a repeatable asset group containing the assets for each ```json { - "format_id": "image_slideshow_5s_each", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "image_slideshow_5s_each" + }, "type": "display", "dimensions": "728x90", "assets_required": [ @@ -143,7 +152,10 @@ Carousel formats define a repeatable asset group containing the assets for each ```json { - "format_id": "mobile_story_vertical", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "mobile_story_vertical" + }, "type": "display", "dimensions": "1080x1920", "assets_required": [ @@ -188,7 +200,10 @@ Carousel formats define a repeatable asset group containing the assets for each ```json { - "format_id": "video_playlist_6s_bumpers", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_playlist_6s_bumpers" + }, "type": "video", "assets_required": [ { @@ -231,7 +246,10 @@ All assets for a given index must be provided together (you cannot have `product ```json { - "format_id": "product_carousel_3_to_10", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "product_carousel_3_to_10" + }, "assets": { "product_0_image": { "asset_type": "image", @@ -294,7 +312,10 @@ All assets for a given index must be provided together (you cannot have `product ```json { - "format_id": "mobile_story_vertical", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "mobile_story_vertical" + }, "assets": { "frame_0_background": { "asset_type": "image", @@ -508,7 +529,10 @@ https://track.brand.com/view?buy={MEDIA_BUY_ID}&item={CAROUSEL_INDEX}&total={CAR ```json { - "format_id": "ecommerce_carousel_300x600", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "ecommerce_carousel_300x600" + }, "name": "E-commerce Product Carousel", "type": "display", "dimensions": "300x600", @@ -566,7 +590,10 @@ https://track.brand.com/view?buy={MEDIA_BUY_ID}&item={CAROUSEL_INDEX}&total={CAR ```json { - "format_id": "ecommerce_carousel_300x600", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "ecommerce_carousel_300x600" + }, "assets": { "product_0_image": { "asset_type": "image", diff --git a/docs/creative/channels/display.md b/docs/creative/channels/display.md index 231099541..ef8d35aae 100644 --- a/docs/creative/channels/display.md +++ b/docs/creative/channels/display.md @@ -21,7 +21,10 @@ Display formats in AdCP include: ```json { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "type": "display", "assets_required": [ { @@ -44,7 +47,10 @@ Display formats in AdCP include: ```json { - "format_id": "display_728x90", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_728x90" + }, "type": "display", "assets_required": [ { @@ -67,7 +73,10 @@ Display formats in AdCP include: ```json { - "format_id": "display_160x600", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_160x600" + }, "type": "display", "assets_required": [ { @@ -90,7 +99,10 @@ Display formats in AdCP include: ```json { - "format_id": "display_970x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_970x250" + }, "type": "display", "assets_required": [ { @@ -113,7 +125,10 @@ Display formats in AdCP include: ```json { - "format_id": "mobile_banner_320x50", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "mobile_banner_320x50" + }, "type": "display", "assets_required": [ { @@ -136,7 +151,10 @@ Display formats in AdCP include: ```json { - "format_id": "mobile_interstitial_320x480", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "mobile_interstitial_320x480" + }, "type": "display", "assets_required": [ { @@ -161,7 +179,10 @@ Display formats in AdCP include: ```json { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "assets": { "banner_image": { "asset_type": "image", @@ -187,7 +208,10 @@ Display formats in AdCP include: ```json { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "assets": { "banner_image": { "asset_type": "image", @@ -212,7 +236,10 @@ Display formats in AdCP include: ```json { - "format_id": "display_300x250_3p", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250_3p" + }, "type": "display", "assets_required": [ { @@ -235,7 +262,10 @@ JavaScript tag manifest: ```json { - "format_id": "display_300x250_3p", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250_3p" + }, "assets": { "tag": { "asset_type": "javascript", @@ -249,7 +279,10 @@ JavaScript tag manifest: ```json { - "format_id": "display_728x90_html", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_728x90_html" + }, "type": "display", "assets_required": [ { @@ -272,7 +305,10 @@ HTML tag manifest: ```json { - "format_id": "display_728x90_html", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_728x90_html" + }, "assets": { "tag": { "asset_type": "html", @@ -290,7 +326,10 @@ HTML5 formats specify multiple assets that the publisher's ad server assembles i ```json { - "format_id": "display_300x250_html5", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250_html5" + }, "type": "display", "assets_required": [ { @@ -341,7 +380,10 @@ HTML5 manifest: ```json { - "format_id": "display_300x250_html5", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250_html5" + }, "assets": { "background_image": { "asset_type": "image", @@ -380,7 +422,10 @@ Responsive formats adapt to multiple sizes based on placement context. ```json { - "format_id": "display_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_responsive" + }, "type": "display", "responsive": true, "supported_sizes": ["300x250", "728x90", "320x50"], @@ -422,7 +467,10 @@ Responsive formats adapt to multiple sizes based on placement context. ```json { - "format_id": "display_970x250_expandable", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_970x250_expandable" + }, "type": "display", "expandable": true, "collapsed_size": "970x250", diff --git a/docs/creative/channels/dooh.md b/docs/creative/channels/dooh.md index ca6ac97d0..93c881b5f 100644 --- a/docs/creative/channels/dooh.md +++ b/docs/creative/channels/dooh.md @@ -21,7 +21,10 @@ DOOH formats differ from other digital formats: ```json { - "format_id": "dooh_billboard_1920x1080", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "dooh_billboard_1920x1080" + }, "type": "dooh", "assets_required": [ { @@ -50,7 +53,10 @@ DOOH formats differ from other digital formats: ```json { - "format_id": "dooh_transit_1080x1920", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "dooh_transit_1080x1920" + }, "type": "dooh", "assets_required": [ { @@ -79,7 +85,10 @@ DOOH formats differ from other digital formats: ```json { - "format_id": "dooh_video_15s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "dooh_video_15s" + }, "type": "dooh", "assets_required": [ { @@ -135,7 +144,10 @@ The mechanics are identical to digital impression tracking - it's just a URL tha ```json { - "format_id": "dooh_billboard_1920x1080", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "dooh_billboard_1920x1080" + }, "assets": { "billboard_image": { "asset_type": "image", @@ -156,7 +168,10 @@ The mechanics are identical to digital impression tracking - it's just a URL tha ```json { - "format_id": "dooh_video_15s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "dooh_video_15s" + }, "assets": { "video_file": { "asset_type": "video", diff --git a/docs/creative/channels/video.md b/docs/creative/channels/video.md index a82b7f2b5..6770672f3 100644 --- a/docs/creative/channels/video.md +++ b/docs/creative/channels/video.md @@ -23,7 +23,10 @@ Video ads play before (pre-roll), during (mid-roll), or after (post-roll) video #### 15-Second Video ```json { - "format_id": "video_15s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_15s" + }, "type": "video", "assets_required": [ { @@ -49,7 +52,10 @@ Video ads play before (pre-roll), during (mid-roll), or after (post-roll) video #### 30-Second Video ```json { - "format_id": "video_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s" + }, "type": "video", "assets_required": [ { @@ -75,7 +81,10 @@ Video ads play before (pre-roll), during (mid-roll), or after (post-roll) video #### 6-Second Bumper ```json { - "format_id": "video_6s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_6s" + }, "type": "video", "assets_required": [ { @@ -101,7 +110,10 @@ Video ads play before (pre-roll), during (mid-roll), or after (post-roll) video ```json { - "format_id": "video_vertical_15s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_vertical_15s" + }, "type": "video", "assets_required": [ { @@ -126,7 +138,10 @@ Video ads play before (pre-roll), during (mid-roll), or after (post-roll) video ```json { - "format_id": "video_30s_ctv", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_ctv" + }, "type": "video", "assets_required": [ { @@ -156,7 +171,10 @@ For third-party ad servers: ```json { - "format_id": "video_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vast" + }, "type": "video", "assets_required": [ { @@ -177,7 +195,10 @@ For third-party ad servers: ```json { - "format_id": "video_30s_vpaid", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vpaid" + }, "type": "video", "assets_required": [ { @@ -201,7 +222,10 @@ For third-party ad servers: ```json { - "format_id": "video_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s" + }, "assets": { "video_file": { "asset_type": "video", @@ -231,7 +255,10 @@ For third-party ad servers: ```json { - "format_id": "video_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vast" + }, "assets": { "vast_tag": { "asset_type": "url", @@ -246,7 +273,10 @@ For third-party ad servers: ```json { - "format_id": "video_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vast" + }, "assets": { "vast_xml": { "asset_type": "vast_xml", @@ -260,7 +290,10 @@ For third-party ad servers: ```json { - "format_id": "video_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s" + }, "assets": { "video_1080p": { "asset_type": "video", @@ -340,7 +373,10 @@ https://track.brand.com/imp? ```json { - "format_id": "video_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s" + }, "assets": { "video_file": { "asset_type": "video", @@ -465,7 +501,10 @@ VPAID (Video Player Ad-Serving Interface Definition) enables interactive video a ```json { - "format_id": "video_30s_vpaid", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vpaid" + }, "assets_required": [ { "asset_id": "vpaid_tag", diff --git a/docs/creative/creative-manifests.md b/docs/creative/creative-manifests.md index db2effc3b..6ab94276a 100644 --- a/docs/creative/creative-manifests.md +++ b/docs/creative/creative-manifests.md @@ -69,7 +69,10 @@ Static manifests contain all assets ready for immediate rendering. These are pro ```json { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "assets": { "hero_image": { "asset_type": "image", @@ -114,7 +117,10 @@ Dynamic manifests include endpoints or code for real-time generation. These are ```json { - "format_id": "display_dynamic_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_dynamic_300x250" + }, "assets": { "dynamic_content": { "asset_type": "webhook", @@ -156,7 +162,10 @@ Digital Out-of-Home (DOOH) creatives use impression tracking just like other for ```json { - "format_id": "dooh_billboard_1920x1080", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "dooh_billboard_1920x1080" + }, "promoted_offering": "Premium Coffee Blend", "assets": { "billboard_image": { @@ -196,7 +205,10 @@ Construct manifests directly by pairing format requirements with your assets: ```json { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "promoted_offering": "Premium Salmon Formula", "assets": { "hero_image": { @@ -234,9 +246,15 @@ Use the `preview_creative` task to see how a manifest will render: ```json { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "creative_manifest": { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "assets": { "hero_image": { "url": "https://cdn.example.com/hero.jpg", @@ -267,9 +285,15 @@ Manifests are submitted to the creative library using `sync_creatives`, then ref { "creative_id": "native-salmon-v1", "name": "Salmon Special Native Ad", - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "manifest": { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "promoted_offering": "Fresh Pacific Salmon", "assets": { "headline": { diff --git a/docs/creative/formats.md b/docs/creative/formats.md index 5f8bebdda..38f393269 100644 --- a/docs/creative/formats.md +++ b/docs/creative/formats.md @@ -48,8 +48,10 @@ Buyers discover available formats using the `list_creative_formats` task, which { "formats": [ { - "format_id": "homepage_takeover_2024", - "agent_url": "https://youragent.com", + "format_id": { + "agent_url": "https://youragent.com", + "id": "homepage_takeover_2024" + }, "name": "Homepage Takeover", "type": "rich_media" } @@ -70,8 +72,10 @@ Each format includes an `agent_url` field pointing to its authoritative source: ```json { - "format_id": "video_30s_hosted", - "agent_url": "https://creative.adcontextprotocol.org", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_hosted" + }, "name": "Standard 30-Second Video" } ``` @@ -115,7 +119,10 @@ Formats include two optional fields for visual presentation in format browsing U **Example**: ```json { - "format_id": "homepage_takeover_premium", + "format_id": { + "agent_url": "https://publisher.com", + "id": "homepage_takeover_premium" + }, "name": "Premium Homepage Takeover", "description": "Full-screen immersive experience with video, carousel, and companion units", "preview_image": "https://publisher.com/format-cards/homepage-takeover.png", @@ -205,8 +212,10 @@ Formats are JSON objects with the following key fields: ```json { - "format_id": "video_30s_hosted", - "agent_url": "https://creative.adcontextprotocol.org", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_hosted" + }, "name": "30-Second Hosted Video", "type": "video", "assets_required": [ @@ -239,7 +248,10 @@ Visual formats (display, dooh, native) include structured `render_dimensions` fo ```json { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "type": "display", "render_dimensions": { "width": 300, diff --git a/docs/creative/generative-creative.md b/docs/creative/generative-creative.md index 8e98b4611..0b7ce5b82 100644 --- a/docs/creative/generative-creative.md +++ b/docs/creative/generative-creative.md @@ -23,7 +23,10 @@ Here's the simplest possible request to generate a native display ad: ```json { "message": "Create a simple ad for a coffee shop promotion - 20% off all drinks this week", - "format_id": "display_native", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_native" + }, "output_mode": "manifest" } ``` @@ -36,10 +39,9 @@ You'll receive a structured creative manifest: { "context_id": "ctx-coffee-123", "creative": { - "format": { - "id": "display_native", - "name": "Native Display Ad", - "type": "display" + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_native" }, "output_mode": "manifest", "assets": [ @@ -87,7 +89,10 @@ Provide brand context for better creative generation: ```json { "message": "Create a display ad for our coffee shop promotion", - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "brand_manifest": { "url": "https://mycoffeeshop.com", "name": "Brew & Co", @@ -106,7 +111,10 @@ Provide brand context for better creative generation: ```json { "message": "Create a coffee shop ad", - "format_id": "display_native", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_native" + }, "brand_manifest": { "url": "https://mycoffeeshop.com" } @@ -122,7 +130,10 @@ Provide existing assets to incorporate into the creative: ```json { "message": "Create a display ad featuring our signature latte", - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "brand_manifest": { "url": "https://mycoffeeshop.com" }, @@ -145,7 +156,10 @@ For real-time personalization, use code mode: ```json { "message": "Create a weather-responsive coffee ad that shows hot drinks when cold, iced drinks when warm", - "format_id": "display_native", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_native" + }, "output_mode": "code" } ``` @@ -166,8 +180,10 @@ For custom publisher formats, specify the source: ```json { "message": "Create a premium video ad", - "format_source": "https://premium-publisher.com/.well-known/adcp/sales", - "format_id": "premium_video_15s", + "format_id": { + "agent_url": "https://premium-publisher.com", + "id": "premium_video_15s" + }, "output_mode": "manifest" } ``` diff --git a/docs/creative/implementing-creative-agents.md b/docs/creative/implementing-creative-agents.md index 9dd08c01c..8074f7a31 100644 --- a/docs/creative/implementing-creative-agents.md +++ b/docs/creative/implementing-creative-agents.md @@ -46,8 +46,10 @@ When formats reference your agent_url, you are the authority for: ```json { - "format_id": "youragency.com:story_sequence_5frame", - "agent_url": "https://youragency.com", + "format_id": { + "agent_url": "https://youragency.com", + "id": "story_sequence_5frame" + }, "name": "5-Frame Story Sequence", "type": "display", "min_frames": 5, @@ -193,8 +195,10 @@ You're a creative agency building custom formats for brands: ```json { - "format_id": "brandstudio.com:hero_video_package", - "agent_url": "https://brandstudio.com", + "format_id": { + "agent_url": "https://brandstudio.com", + "id": "hero_video_package" + }, "name": "Hero Video Package", "type": "video", "description": "Premium video creative with multiple aspect ratios", @@ -212,8 +216,10 @@ You're a platform defining specialized formats: ```json { - "format_id": "platform.com:interactive_quiz", - "agent_url": "https://platform.com", + "format_id": { + "agent_url": "https://platform.com", + "id": "interactive_quiz" + }, "name": "Interactive Quiz Ad", "type": "rich_media", "description": "Engagement-driven quiz format", @@ -231,8 +237,10 @@ You provide enhanced versions of standard formats: ```json { - "format_id": "enhanced.com:video_30s_optimized", - "agent_url": "https://enhanced.com", + "format_id": { + "agent_url": "https://enhanced.com", + "id": "video_30s_optimized" + }, "name": "Optimized 30s Video", "type": "video", "extends": "creative.adcontextprotocol.org:video_30s", diff --git a/docs/creative/task-reference/list_creative_formats.md b/docs/creative/task-reference/list_creative_formats.md index f10258942..f535cec3e 100644 --- a/docs/creative/task-reference/list_creative_formats.md +++ b/docs/creative/task-reference/list_creative_formats.md @@ -47,7 +47,10 @@ Buyers can recursively query creative_agents to discover all available formats. "capabilities": ["validation", "assembly", "preview"], "formats": [ { - "format_id": "video_standard_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_standard_30s" + }, "name": "Standard Video - 30 seconds", "type": "video", "iab_specification": "https://iabtechlab.com/standards/video-ad-serving-template-vast/", @@ -104,7 +107,10 @@ Response: "capabilities": ["validation", "assembly", "preview"], "formats": [ { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "agent_url": "https://creative.adcontextprotocol.org", "name": "Medium Rectangle", "type": "display", @@ -145,7 +151,10 @@ Response: "capabilities": ["validation", "assembly", "generation", "preview"], "formats": [ { - "format_id": "display_728x90_3p", + "format_id": { + "agent_url": "https://dco.example.com", + "id": "display_728x90_3p" + }, "agent_url": "https://dco.example.com", "name": "Leaderboard - Third Party", "type": "display", diff --git a/docs/creative/task-reference/preview_creative.md b/docs/creative/task-reference/preview_creative.md index f7c3538af..364b74125 100644 --- a/docs/creative/task-reference/preview_creative.md +++ b/docs/creative/task-reference/preview_creative.md @@ -13,7 +13,10 @@ The simplest preview request returns a single URL you can iframe: ```json { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "creative_manifest": { /* your creative */ } } ``` @@ -192,9 +195,15 @@ Request previews for desktop, mobile, and tablet: ```json { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "creative_manifest": { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "assets": { "hero_image": { "asset_type": "image", @@ -294,9 +303,15 @@ Preview a dynamic creative with different geographic and device contexts: ```json { - "format_id": "display_dynamic_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_dynamic_300x250" + }, "creative_manifest": { - "format_id": "display_dynamic_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_dynamic_300x250" + }, "assets": { "dynamic_endpoint": { "asset_type": "dynamic_endpoint", @@ -378,9 +393,15 @@ Preview an audio ad with AI-generated host reads for different podcast contexts: ```json { - "format_id": "audio_host_read_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_host_read_30s" + }, "creative_manifest": { - "format_id": "audio_host_read_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_host_read_30s" + }, "assets": { "script_template": { "asset_type": "text", @@ -465,9 +486,15 @@ Preview a video creative with geo-specific end cards: ```json { - "format_id": "video_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vast" + }, "creative_manifest": { - "format_id": "video_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vast" + }, "assets": { "vast_tag": { "asset_type": "vast_tag", @@ -540,9 +567,15 @@ Preview a dynamic creative that uses template variables for personalization: ```json { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "creative_manifest": { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "native_responsive" + }, "assets": { "headline": { "asset_type": "text", diff --git a/docs/creative/universal-macros.md b/docs/creative/universal-macros.md index 2577d22a6..ce3780565 100644 --- a/docs/creative/universal-macros.md +++ b/docs/creative/universal-macros.md @@ -163,7 +163,10 @@ For video ads in commercial breaks: ```json { "creative_id": "cr_video_30s", - "format_id": "video_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vast" + }, "assets": [ { "asset_id": "vast_xml", @@ -185,7 +188,10 @@ For video ads in commercial breaks: ```json { "creative_id": "cr_banner_300x250", - "format_id": "display_banner_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_banner_300x250" + }, "assets": [ { "asset_id": "banner_image", @@ -213,7 +219,10 @@ For video ads in commercial breaks: ```json { "creative_id": "cr_audio_30s", - "format_id": "audio_streaming_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_streaming_30s" + }, "assets": [ { "asset_id": "audio_file", @@ -303,7 +312,10 @@ Query `list_creative_formats` to see which macros each format supports: ```json { - "format_id": "video_30s_vast", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_30s_vast" + }, "type": "video", "supported_macros": [ { diff --git a/docs/media-buy/capability-discovery/implementing-standard-formats.md b/docs/media-buy/capability-discovery/implementing-standard-formats.md index fd37e5bc1..852f9464d 100644 --- a/docs/media-buy/capability-discovery/implementing-standard-formats.md +++ b/docs/media-buy/capability-discovery/implementing-standard-formats.md @@ -192,7 +192,10 @@ The buyer tracks which URLs they've queried to avoid infinite loops. { "formats": [ { - "format_id": "native_feed_card", + "format_id": { + "agent_url": "https://youragent.com", + "id": "native_feed_card" + }, "agent_url": "https://youragent.com", "type": "native" } @@ -209,9 +212,9 @@ The buyer tracks which URLs they've queried to avoid infinite loops. ```json { "formats": [ - {"format_id": "display_300x250", "agent_url": "https://youragent.com"}, - {"format_id": "display_728x90", "agent_url": "https://youragent.com"}, - {"format_id": "display_320x50", "agent_url": "https://youragent.com"}, + {"format_id": {"agent_url": "https://youragent.com", "id": "display_300x250"}, "agent_url": "https://youragent.com"}, + {"format_id": {"agent_url": "https://youragent.com", "id": "display_728x90"}, "agent_url": "https://youragent.com"}, + {"format_id": {"agent_url": "https://youragent.com", "id": "display_320x50"}, "agent_url": "https://youragent.com"}, // ... copying 50+ standard formats ] } @@ -288,7 +291,10 @@ This ensures the domain in the namespace is a valid, discoverable agent that can { "formats": [ { - "format_id": "youragent.com:homepage_takeover", + "format_id": { + "agent_url": "https://youragent.com", + "id": "homepage_takeover" + }, "agent_url": "https://youragent.com", "name": "Homepage Takeover", "type": "rich_media" @@ -308,7 +314,10 @@ This ensures the domain in the namespace is a valid, discoverable agent that can **Reference Creative Agent:** ```json { - "format_id": "creative.adcontextprotocol.org:display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "agent_url": "https://creative.adcontextprotocol.org" } ``` @@ -316,7 +325,10 @@ This ensures the domain in the namespace is a valid, discoverable agent that can **Publisher Sales Agent:** ```json { - "format_id": "youragent.com:custom_format", + "format_id": { + "agent_url": "https://youragent.com", + "id": "custom_format" + }, "agent_url": "https://youragent.com" } ``` @@ -324,7 +336,10 @@ This ensures the domain in the namespace is a valid, discoverable agent that can **DCO Platform:** ```json { - "format_id": "dco.example:dynamic_creative_v2", + "format_id": { + "agent_url": "https://dco.example", + "id": "dynamic_creative_v2" + }, "agent_url": "https://dco.example" } ``` @@ -337,11 +352,17 @@ With namespaced format_ids, conflicts **cannot occur** - each domain controls it ```json // Two different formats, both valid { - "format_id": "publisher-a.com:video_30s", + "format_id": { + "agent_url": "https://publisher-a.com", + "id": "video_30s" + }, "agent_url": "https://publisher-a.com" } { - "format_id": "publisher-b.com:video_30s", + "format_id": { + "agent_url": "https://publisher-b.com", + "id": "video_30s" + }, "agent_url": "https://publisher-b.com" } ``` @@ -354,13 +375,19 @@ If a buyer encounters the same namespaced format_id from multiple sources, they ```json // ✅ Valid - domain matches { - "format_id": "youragent.com:format_x", + "format_id": { + "agent_url": "https://youragent.com", + "id": "format_x" + }, "agent_url": "https://youragent.com" } // ❌ Invalid - domain mismatch { - "format_id": "otheragent.com:format_x", + "format_id": { + "agent_url": "https://otheragent.com", + "id": "format_x" + }, "agent_url": "https://youragent.com" } ``` @@ -382,7 +409,10 @@ If you previously used simple IDs like `display_300x250`, migrate to namespaced **Before:** ```json { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://youragent.com", + "id": "display_300x250_old" + }, "agent_url": "https://youragent.com" } ``` @@ -390,7 +420,10 @@ If you previously used simple IDs like `display_300x250`, migrate to namespaced **After:** ```json { - "format_id": "youragent.com:display_300x250", + "format_id": { + "agent_url": "https://youragent.com", + "id": "display_300x250" + }, "agent_url": "https://youragent.com" } ``` @@ -403,7 +436,10 @@ Each format includes an `agent_url` field indicating its authoritative source: ```json { - "format_id": "creative.adcontextprotocol.org:display_300x250", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_300x250" + }, "agent_url": "https://creative.adcontextprotocol.org", "name": "Medium Rectangle", "type": "display" diff --git a/docs/media-buy/task-reference/get_products.md b/docs/media-buy/task-reference/get_products.md index 9cc85282c..69f7c6191 100644 --- a/docs/media-buy/task-reference/get_products.md +++ b/docs/media-buy/task-reference/get_products.md @@ -138,7 +138,7 @@ Products include **EITHER** `properties` (for specific property lists) **OR** `p - **property_tags**: Array of tags referencing groups of properties (alternative to `properties` array) - Use [`list_authorized_properties`](./list_authorized_properties) to resolve tags to actual property objects - Recommended for products with large property sets (e.g., radio networks with 1000+ stations) -- **format_ids**: Array of supported creative format IDs (strings) - use `list_creative_formats` to get full format details +- **format_ids**: Array of supported creative format ID objects (structured with `agent_url` and `id` fields) - use `list_creative_formats` to get full format details - **delivery_type**: Either `"guaranteed"` or `"non_guaranteed"` - **is_fixed_price**: Whether this product has fixed pricing (true) or uses auction (false) - **cpm**: Cost per thousand impressions (for guaranteed/fixed price products) diff --git a/docs/media-buy/task-reference/list_creative_formats.md b/docs/media-buy/task-reference/list_creative_formats.md index 4473b21e2..9d6b3403f 100644 --- a/docs/media-buy/task-reference/list_creative_formats.md +++ b/docs/media-buy/task-reference/list_creative_formats.md @@ -54,7 +54,10 @@ This ensures you discover all formats capable of rendering into your available p { "formats": [ { - "format_id": "video_standard_30s", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "video_standard_30s" + }, "agent_url": "https://sales-agent.example.com", "name": "Standard Video - 30 seconds", "type": "video", @@ -62,7 +65,10 @@ This ensures you discover all formats capable of rendering into your available p "assets_required": [ /* ... */ ] }, { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "display_300x250" + }, "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle Banner", "type": "display" @@ -119,7 +125,10 @@ The AdCP payload is identical across protocols. Only the request/response wrappe { "formats": [ { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "display_300x250" + }, "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle", "type": "display", @@ -145,7 +154,10 @@ The AdCP payload is identical across protocols. Only the request/response wrappe ] }, { - "format_id": "native_responsive", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "native_responsive" + }, "agent_url": "https://sales-agent.example.com", "name": "Responsive Native Ad", "type": "display", @@ -196,7 +208,10 @@ The AdCP payload is identical across protocols. Only the request/response wrappe { "formats": [ { - "format_id": "display_300x250_3p", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "display_300x250_3p" + }, "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle - Third Party", "type": "display", @@ -277,7 +292,10 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w { "formats": [ { - "format_id": "video_vertical_15s", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "video_vertical_15s" + }, "agent_url": "https://sales-agent.example.com", "name": "15-Second Vertical Video", "type": "video", @@ -298,7 +316,10 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w ] }, { - "format_id": "display_vertical_mobile", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "display_vertical_mobile" + }, "agent_url": "https://sales-agent.example.com", "name": "Vertical Mobile Banner", "type": "display", @@ -336,7 +357,10 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w { "formats": [ { - "format_id": "video_15s_hosted", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "video_15s_hosted" + }, "agent_url": "https://sales-agent.example.com", "name": "15-Second Hosted Video", "type": "video", @@ -357,7 +381,10 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w ] }, { - "format_id": "display_300x250", + "format_id": { + "agent_url": "https://sales-agent.example.com", + "id": "display_300x250" + }, "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle", "type": "display", @@ -391,7 +418,10 @@ I found 2 audio formats available. The standard 30-second format is recommended { "formats": [ { - "format_id": "audio_standard_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "audio_standard_30s" + }, "name": "Standard Audio - 30 seconds", "type": "audio", "iab_specification": "DAAST 1.0", @@ -403,7 +433,10 @@ I found 2 audio formats available. The standard 30-second format is recommended } }, { - "format_id": "display_carousel_5", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_carousel_5" + }, "name": "Product Carousel - 5 Items", "type": "display", "assets_required": [ @@ -487,7 +520,10 @@ await a2a.send({ "data": { "formats": [ { - "format_id": "video_standard_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_standard_30s" + }, "name": "Standard Video - 30 seconds", "type": "video", "iab_specification": "VAST 4.2", @@ -532,7 +568,10 @@ Found 8 standard video formats following IAB VAST specifications. The 30-second { "formats": [ { - "format_id": "video_standard_30s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_standard_30s" + }, "name": "Standard Video - 30 seconds", "type": "video", "iab_specification": "VAST 4.2", @@ -545,7 +584,10 @@ Found 8 standard video formats following IAB VAST specifications. The 30-second } }, { - "format_id": "video_standard_15s", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "video_standard_15s" + }, "name": "Standard Video - 15 seconds", "type": "video", "iab_specification": "VAST 4.2", @@ -581,7 +623,10 @@ I found 15 display formats including standard IAB sizes and innovative formats l { "formats": [ { - "format_id": "display_carousel_5", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "display_carousel_5" + }, "name": "Product Carousel - 5 Items", "type": "display", "assets_required": [ From 88e1562acd401a796674c1c269eacac9a8321fa5 Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Thu, 16 Oct 2025 21:59:24 -0400 Subject: [PATCH 2/3] Fix format_id in standard format schemas: use structured $ref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated all 15 standard format schema files to reference the structured format-id.json schema instead of using plain string constants. Before: "format_id": {"type": "string", "const": "display_300x250"} After: "format_id": {"$ref": "/schemas/v1/core/format-id.json"} This ensures standard formats properly validate against the structured format ID object with agent_url and id fields. Files updated: - Display formats (7 files) - Video formats (5 files) - Native, foundational, and retail formats (3 files) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../schemas/v1/standard-formats/display/display_160x600.json | 3 +-- .../schemas/v1/standard-formats/display/display_300x250.json | 3 +-- .../schemas/v1/standard-formats/display/display_336x280.json | 3 +-- static/schemas/v1/standard-formats/display/display_728x90.json | 3 +-- .../schemas/v1/standard-formats/display/display_970x250.json | 3 +-- .../v1/standard-formats/display/display_dynamic_300x250.json | 3 +-- .../standard-formats/display/mobile_interstitial_320x480.json | 3 +-- .../foundational/foundational_immersive_canvas.json | 3 +-- .../schemas/v1/standard-formats/native/native_responsive.json | 3 +-- .../v1/standard-formats/retail/retail_product_carousel.json | 3 +-- .../v1/standard-formats/video/foundational_video_15s.json | 3 +-- .../v1/standard-formats/video/video_non_skippable_30s.json | 3 +-- .../v1/standard-formats/video/video_outstream_native.json | 3 +-- .../schemas/v1/standard-formats/video/video_skippable_15s.json | 3 +-- .../v1/standard-formats/video/video_story_vertical.json | 3 +-- 15 files changed, 15 insertions(+), 30 deletions(-) diff --git a/static/schemas/v1/standard-formats/display/display_160x600.json b/static/schemas/v1/standard-formats/display/display_160x600.json index 31edf03e5..a3721535e 100644 --- a/static/schemas/v1/standard-formats/display/display_160x600.json +++ b/static/schemas/v1/standard-formats/display/display_160x600.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "display_160x600" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/display/display_300x250.json b/static/schemas/v1/standard-formats/display/display_300x250.json index e9cf915b6..cd999df61 100644 --- a/static/schemas/v1/standard-formats/display/display_300x250.json +++ b/static/schemas/v1/standard-formats/display/display_300x250.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "display_300x250" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/display/display_336x280.json b/static/schemas/v1/standard-formats/display/display_336x280.json index 2e1e8f250..cc4e0490a 100644 --- a/static/schemas/v1/standard-formats/display/display_336x280.json +++ b/static/schemas/v1/standard-formats/display/display_336x280.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "display_336x280" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/display/display_728x90.json b/static/schemas/v1/standard-formats/display/display_728x90.json index f9a80caba..4efd60100 100644 --- a/static/schemas/v1/standard-formats/display/display_728x90.json +++ b/static/schemas/v1/standard-formats/display/display_728x90.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "display_728x90" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/display/display_970x250.json b/static/schemas/v1/standard-formats/display/display_970x250.json index da16214a5..9d49afad7 100644 --- a/static/schemas/v1/standard-formats/display/display_970x250.json +++ b/static/schemas/v1/standard-formats/display/display_970x250.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "display_970x250" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/display/display_dynamic_300x250.json b/static/schemas/v1/standard-formats/display/display_dynamic_300x250.json index 139ab36fd..6e82978d9 100644 --- a/static/schemas/v1/standard-formats/display/display_dynamic_300x250.json +++ b/static/schemas/v1/standard-formats/display/display_dynamic_300x250.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "display_dynamic_300x250" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/display/mobile_interstitial_320x480.json b/static/schemas/v1/standard-formats/display/mobile_interstitial_320x480.json index 8fe2504a2..8cdefadc9 100644 --- a/static/schemas/v1/standard-formats/display/mobile_interstitial_320x480.json +++ b/static/schemas/v1/standard-formats/display/mobile_interstitial_320x480.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "mobile_interstitial_320x480" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/foundational/foundational_immersive_canvas.json b/static/schemas/v1/standard-formats/foundational/foundational_immersive_canvas.json index dc427be20..b0f17b888 100644 --- a/static/schemas/v1/standard-formats/foundational/foundational_immersive_canvas.json +++ b/static/schemas/v1/standard-formats/foundational/foundational_immersive_canvas.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "foundational_immersive_canvas" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/native/native_responsive.json b/static/schemas/v1/standard-formats/native/native_responsive.json index 8a595ed59..3376ae3c8 100644 --- a/static/schemas/v1/standard-formats/native/native_responsive.json +++ b/static/schemas/v1/standard-formats/native/native_responsive.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "native_responsive" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/retail/retail_product_carousel.json b/static/schemas/v1/standard-formats/retail/retail_product_carousel.json index 1e372624f..b3c239b02 100644 --- a/static/schemas/v1/standard-formats/retail/retail_product_carousel.json +++ b/static/schemas/v1/standard-formats/retail/retail_product_carousel.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "retail_product_carousel" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/video/foundational_video_15s.json b/static/schemas/v1/standard-formats/video/foundational_video_15s.json index 69852fa77..606494635 100644 --- a/static/schemas/v1/standard-formats/video/foundational_video_15s.json +++ b/static/schemas/v1/standard-formats/video/foundational_video_15s.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "foundational_video_15s" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/video/video_non_skippable_30s.json b/static/schemas/v1/standard-formats/video/video_non_skippable_30s.json index 179e33ab0..8bf39c3cc 100644 --- a/static/schemas/v1/standard-formats/video/video_non_skippable_30s.json +++ b/static/schemas/v1/standard-formats/video/video_non_skippable_30s.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "video_non_skippable_30s" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/video/video_outstream_native.json b/static/schemas/v1/standard-formats/video/video_outstream_native.json index 15c43c6a3..6a7816c60 100644 --- a/static/schemas/v1/standard-formats/video/video_outstream_native.json +++ b/static/schemas/v1/standard-formats/video/video_outstream_native.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "video_outstream_native" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/video/video_skippable_15s.json b/static/schemas/v1/standard-formats/video/video_skippable_15s.json index b31ecf899..a1ca1228b 100644 --- a/static/schemas/v1/standard-formats/video/video_skippable_15s.json +++ b/static/schemas/v1/standard-formats/video/video_skippable_15s.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "video_skippable_15s" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", diff --git a/static/schemas/v1/standard-formats/video/video_story_vertical.json b/static/schemas/v1/standard-formats/video/video_story_vertical.json index 662f9d9b8..dbdfa25cd 100644 --- a/static/schemas/v1/standard-formats/video/video_story_vertical.json +++ b/static/schemas/v1/standard-formats/video/video_story_vertical.json @@ -6,8 +6,7 @@ "type": "object", "properties": { "format_id": { - "type": "string", - "const": "video_story_vertical" + "$ref": "/schemas/v1/core/format-id.json" }, "type": { "type": "string", From 0d6b776dd5cdc5937754bd775c7fecb254fb6947 Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Thu, 16 Oct 2025 22:10:02 -0400 Subject: [PATCH 3/3] Remove redundant agent_url field from format objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The agent_url was appearing both inside format_id (correct) and as a top-level field in format objects (redundant). Since format_id is now a structured object containing agent_url, the separate field is unnecessary. Changes: - Removed agent_url from format.json schema - Removed 24 redundant agent_url occurrences from documentation examples - format objects now only have agent_url inside format_id Files updated: - static/schemas/v1/core/format.json - docs/media-buy/capability-discovery/implementing-standard-formats.md (11) - docs/media-buy/task-reference/list_creative_formats.md (9) - docs/creative/task-reference/list_creative_formats.md (4) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../task-reference/list_creative_formats.md | 14 ++++--- .../implementing-standard-formats.md | 38 +++++++------------ .../task-reference/list_creative_formats.md | 9 ----- static/schemas/v1/core/format.json | 5 --- 4 files changed, 21 insertions(+), 45 deletions(-) diff --git a/docs/creative/task-reference/list_creative_formats.md b/docs/creative/task-reference/list_creative_formats.md index f535cec3e..0032ac684 100644 --- a/docs/creative/task-reference/list_creative_formats.md +++ b/docs/creative/task-reference/list_creative_formats.md @@ -111,7 +111,6 @@ Response: "agent_url": "https://creative.adcontextprotocol.org", "id": "display_300x250" }, - "agent_url": "https://creative.adcontextprotocol.org", "name": "Medium Rectangle", "type": "display", "assets_required": [ @@ -155,7 +154,6 @@ Response: "agent_url": "https://dco.example.com", "id": "display_728x90_3p" }, - "agent_url": "https://dco.example.com", "name": "Leaderboard - Third Party", "type": "display", "dimensions": "728x90", @@ -251,8 +249,10 @@ Response: "capabilities": ["validation", "assembly", "generation", "preview"], "formats": [ { - "format_id": "300x250_banner_generative", - "agent_url": "https://creative.adcontextprotocol.org", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "300x250_banner_generative" + }, "name": "300x250 Generative Banner", "type": "display", "assets_required": [ @@ -274,8 +274,10 @@ Response: "description": "Accepts a brand manifest and message, generates a complete 300x250 banner creative" }, { - "format_id": "300x250_banner_image", - "agent_url": "https://creative.adcontextprotocol.org", + "format_id": { + "agent_url": "https://creative.adcontextprotocol.org", + "id": "300x250_banner_image" + }, "name": "300x250 Standard Banner", "type": "display", "assets_required": [ diff --git a/docs/media-buy/capability-discovery/implementing-standard-formats.md b/docs/media-buy/capability-discovery/implementing-standard-formats.md index 852f9464d..6c30585b8 100644 --- a/docs/media-buy/capability-discovery/implementing-standard-formats.md +++ b/docs/media-buy/capability-discovery/implementing-standard-formats.md @@ -196,7 +196,6 @@ The buyer tracks which URLs they've queried to avoid infinite loops. "agent_url": "https://youragent.com", "id": "native_feed_card" }, - "agent_url": "https://youragent.com", "type": "native" } ] @@ -212,9 +211,9 @@ The buyer tracks which URLs they've queried to avoid infinite loops. ```json { "formats": [ - {"format_id": {"agent_url": "https://youragent.com", "id": "display_300x250"}, "agent_url": "https://youragent.com"}, - {"format_id": {"agent_url": "https://youragent.com", "id": "display_728x90"}, "agent_url": "https://youragent.com"}, - {"format_id": {"agent_url": "https://youragent.com", "id": "display_320x50"}, "agent_url": "https://youragent.com"}, + {"format_id": {"agent_url": "https://youragent.com", "id": "display_300x250"}}, + {"format_id": {"agent_url": "https://youragent.com", "id": "display_728x90"}}, + {"format_id": {"agent_url": "https://youragent.com", "id": "display_320x50"}}, // ... copying 50+ standard formats ] } @@ -295,7 +294,6 @@ This ensures the domain in the namespace is a valid, discoverable agent that can "agent_url": "https://youragent.com", "id": "homepage_takeover" }, - "agent_url": "https://youragent.com", "name": "Homepage Takeover", "type": "rich_media" } @@ -317,8 +315,7 @@ This ensures the domain in the namespace is a valid, discoverable agent that can "format_id": { "agent_url": "https://creative.adcontextprotocol.org", "id": "display_300x250" - }, - "agent_url": "https://creative.adcontextprotocol.org" + } } ``` @@ -328,8 +325,7 @@ This ensures the domain in the namespace is a valid, discoverable agent that can "format_id": { "agent_url": "https://youragent.com", "id": "custom_format" - }, - "agent_url": "https://youragent.com" + } } ``` @@ -339,8 +335,7 @@ This ensures the domain in the namespace is a valid, discoverable agent that can "format_id": { "agent_url": "https://dco.example", "id": "dynamic_creative_v2" - }, - "agent_url": "https://dco.example" + } } ``` @@ -355,15 +350,13 @@ With namespaced format_ids, conflicts **cannot occur** - each domain controls it "format_id": { "agent_url": "https://publisher-a.com", "id": "video_30s" - }, - "agent_url": "https://publisher-a.com" + } } { "format_id": { "agent_url": "https://publisher-b.com", "id": "video_30s" - }, - "agent_url": "https://publisher-b.com" + } } ``` @@ -378,8 +371,7 @@ If a buyer encounters the same namespaced format_id from multiple sources, they "format_id": { "agent_url": "https://youragent.com", "id": "format_x" - }, - "agent_url": "https://youragent.com" + } } // ❌ Invalid - domain mismatch @@ -387,8 +379,7 @@ If a buyer encounters the same namespaced format_id from multiple sources, they "format_id": { "agent_url": "https://otheragent.com", "id": "format_x" - }, - "agent_url": "https://youragent.com" + } } ``` @@ -412,8 +403,7 @@ If you previously used simple IDs like `display_300x250`, migrate to namespaced "format_id": { "agent_url": "https://youragent.com", "id": "display_300x250_old" - }, - "agent_url": "https://youragent.com" + } } ``` @@ -423,8 +413,7 @@ If you previously used simple IDs like `display_300x250`, migrate to namespaced "format_id": { "agent_url": "https://youragent.com", "id": "display_300x250" - }, - "agent_url": "https://youragent.com" + } } ``` @@ -432,7 +421,7 @@ Support both during transition if needed, but new implementations should use nam ## Reference Agent as Format Authority -Each format includes an `agent_url` field indicating its authoritative source: +Each format includes a `format_id` field with an `agent_url` indicating its authoritative source: ```json { @@ -440,7 +429,6 @@ Each format includes an `agent_url` field indicating its authoritative source: "agent_url": "https://creative.adcontextprotocol.org", "id": "display_300x250" }, - "agent_url": "https://creative.adcontextprotocol.org", "name": "Medium Rectangle", "type": "display" } diff --git a/docs/media-buy/task-reference/list_creative_formats.md b/docs/media-buy/task-reference/list_creative_formats.md index 9d6b3403f..c16ca4437 100644 --- a/docs/media-buy/task-reference/list_creative_formats.md +++ b/docs/media-buy/task-reference/list_creative_formats.md @@ -58,7 +58,6 @@ This ensures you discover all formats capable of rendering into your available p "agent_url": "https://sales-agent.example.com", "id": "video_standard_30s" }, - "agent_url": "https://sales-agent.example.com", "name": "Standard Video - 30 seconds", "type": "video", "requirements": { /* ... */ }, @@ -69,7 +68,6 @@ This ensures you discover all formats capable of rendering into your available p "agent_url": "https://sales-agent.example.com", "id": "display_300x250" }, - "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle Banner", "type": "display" // ... full format details @@ -129,7 +127,6 @@ The AdCP payload is identical across protocols. Only the request/response wrappe "agent_url": "https://sales-agent.example.com", "id": "display_300x250" }, - "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle", "type": "display", "dimensions": "300x250", @@ -158,7 +155,6 @@ The AdCP payload is identical across protocols. Only the request/response wrappe "agent_url": "https://sales-agent.example.com", "id": "native_responsive" }, - "agent_url": "https://sales-agent.example.com", "name": "Responsive Native Ad", "type": "display", "assets_required": [ @@ -212,7 +208,6 @@ The AdCP payload is identical across protocols. Only the request/response wrappe "agent_url": "https://sales-agent.example.com", "id": "display_300x250_3p" }, - "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle - Third Party", "type": "display", "dimensions": "300x250", @@ -296,7 +291,6 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w "agent_url": "https://sales-agent.example.com", "id": "video_vertical_15s" }, - "agent_url": "https://sales-agent.example.com", "name": "15-Second Vertical Video", "type": "video", "duration": "15s", @@ -320,7 +314,6 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w "agent_url": "https://sales-agent.example.com", "id": "display_vertical_mobile" }, - "agent_url": "https://sales-agent.example.com", "name": "Vertical Mobile Banner", "type": "display", "dimensions": "320x480" @@ -361,7 +354,6 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w "agent_url": "https://sales-agent.example.com", "id": "video_15s_hosted" }, - "agent_url": "https://sales-agent.example.com", "name": "15-Second Hosted Video", "type": "video", "duration": "15s", @@ -385,7 +377,6 @@ Returns formats that adapt to container width (native ads, fluid layouts, full-w "agent_url": "https://sales-agent.example.com", "id": "display_300x250" }, - "agent_url": "https://sales-agent.example.com", "name": "Medium Rectangle", "type": "display", "dimensions": "300x250", diff --git a/static/schemas/v1/core/format.json b/static/schemas/v1/core/format.json index 8333dafd0..69d0a331d 100644 --- a/static/schemas/v1/core/format.json +++ b/static/schemas/v1/core/format.json @@ -9,11 +9,6 @@ "$ref": "/schemas/v1/core/format-id.json", "description": "Structured format identifier with agent URL and format name" }, - "agent_url": { - "type": "string", - "format": "uri", - "description": "Base URL of the agent that provides this format (authoritative source). E.g., 'https://reference.adcp.org', 'https://dco.example.com'" - }, "name": { "type": "string", "description": "Human-readable format name"