diff --git a/schemas/cache/.hashes.json b/schemas/cache/.hashes.json index 2cf6e832..1c162eba 100644 --- a/schemas/cache/.hashes.json +++ b/schemas/cache/.hashes.json @@ -1,275 +1,277 @@ { - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/index.json": "2198c2bad7a906ae5dafe091f56fd78d4b615371018d3eb30a684c484034b3b6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/a2ui/component.json": "e2e7cd33eb37e7f1f14960d20e9382ceb1610554aca852c0074ebac94e21be53", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/a2ui/surface.json": "4b17d4e574c60f2e299dda06c7968c8a3f1f1c9ac6c2d0d5aede3fd6f645bec1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/account/list-accounts-request.json": "34cfcb66b68821a2505456e15d275696f58ac52228b01e6c1f704c4ada665935", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/account/list-accounts-response.json": "0dd28c642c7e453a9a5bd4737a59cc86d85177d2e1143576e5a99af6a43eef7f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/account/sync-accounts-request.json": "760ac2fec82ff8dd07ced634bc55826bd66ece8174ea9cf21b27d3b8fb206233", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/account/sync-accounts-response.json": "2d3456accb107c8556fbc929f9d65d70fd81ed259b9f78166828a4d0d0c4069b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/adagents.json": "1d287cd054339e892c2b372737fe7d74e1d1ae0e6bd2be7a61dcbee3c6fd3e58", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/brand.json": "30eca566345000af0d9181d33367e7306d509b2e468abff068b0df94ecc70065", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/artifact-webhook-payload.json": "72e643d5c4dcd7d0279b7ab1c79c117434f622f37990714b9c08aa39dc55c912", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/artifact.json": "fc46f9434a1f985e45c2a9401705160f89bb14be21153d92f70cc72e502c2b61", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/calibrate-content-request.json": "d701ed16916be7f544e881e91e0c7cb73684db05b7494fffdcdf5288f8b78b89", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/calibrate-content-response.json": "3fd519d6056129dc831699d5d7ce53c9bf527c075872eb835d52c4f134fe6bf3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/content-standards.json": "dcedf6023832e7f7371343f2aee3f3fa34342c4692beb7af84f8643bacd61a75", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/create-content-standards-request.json": "14a5eea4ef313b86ef3381716e09255acae1ff12c4e56ba5e2aa7b4c1fab8612", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/create-content-standards-response.json": "a74c93629ebc80e4d51d6980963a9b17a12bae096139101e5a3014246abb2bb6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/get-content-standards-request.json": "bbda13bdda94164af39d3f8d66356cd20d39ed0cfe9728631dda9345681fc2a7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/get-content-standards-response.json": "cba6ffb9c6154bd39a7349b04322ed81482859938e0ccc1ca1af0369a5bc262a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/get-media-buy-artifacts-request.json": "e496b185b337adfed0a566ba111401c8522f197350cf02f2e3c17c6aadea7128", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/get-media-buy-artifacts-response.json": "f0b009d5aa6f7c7c9f6987d4e40e688f859d4ca8d6f561dc964327e5b41c06f1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/list-content-standards-request.json": "97ca83ba373f2c9666dc8bb8c0de3c1faa80d65db4dbd565899a04ba0494ff3b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/list-content-standards-response.json": "382ad50a5fcae7f3787939794adf1442a3ca752088629018db5579d674214a34", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/update-content-standards-request.json": "460375595d2e774566dac61e50f021c2f93436db11faac8d204ec9c59e50ef41", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/update-content-standards-response.json": "752a8164f995fc50565ab26da4dcd4bc2810cc6f1ef07b335c74279dad579214", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/validate-content-delivery-request.json": "7732c930edc50c9eede04854316e78324c3756f0243231148e73db1eb2273e3f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/content-standards/validate-content-delivery-response.json": "be787700f5bcaf68cb6b01db85cee54d2149d83bbc60a9f6da55b318ff80a1fa", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/account.json": "762889c00c4b1ac8a9167e9100fc846f59ee8c3bad22ede4935c8374b9fae0f4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/activation-key.json": "216a4e974586f2618fcdd7c08c3aa5920efc3f4400d8df05f234a940bee15b7f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/audio-asset.json": "36dee8ca77bd848a3ac3753e7e4e4c5166b2231e2703a8cb38f3930b176aa768", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/css-asset.json": "d52b3d8c51eba91308352c5986235f8645ab0ac5ac10c5c87ebe6991791e96e7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/daast-asset.json": "a7320c1b786726a6d04803bc5a2524c34d0adeb774ad50fe852aa01b3e9ccb34", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/html-asset.json": "816e1d757b3797d4eb408b92b3e151236ae9d0a2e26074598b35895c7994b644", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/image-asset.json": "c98545787a2951df5db11680627c351f8843a8822b81ed926cedf31d5847df30", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/javascript-asset.json": "26d3c10cde16cd38c2965d1ca25429c170e422e4c610f0868531b2b0ca983df1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/text-asset.json": "1dd471c838d5fcd7178ced070ef1229bb73104925f01376e4ae3e9669ea66fd7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/url-asset.json": "f401bf30ffa14721f7c202da9305cbe68ac1969aca2bb28f56197e9ad36561cb", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/vast-asset.json": "7cfe3bbdb3d7d65705cd296303feb02a625314e1ab58b2aeb98b50b9b0c75f8b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/video-asset.json": "0a2b3748aa5597539e9b25f084366e85cc0542ed702f4d047766fad151f06b10", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/assets/webhook-asset.json": "77d302d7369f6a7f97945f52ff22ab791861e201295778dcd7f0becdd3e1f6bc", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/async-response-data.json": "cae02a03d7dd4b59af82d68733afee6f39cf889db33bdcca295dd96ce70c2239", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/attribution-window.json": "2c7e2ffbe53d97b18e005f97429d2b6daf2bc333ce68edd83759e7fd01b6cfe9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/brand-id.json": "9f0491d5b6a4bb616bc0091dc52b95b2b7cc5c905bbd505586a28cbade0eead1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/brand-manifest-ref.json": "9105b8c0ceb88d332e452011d43f4d659ce7da3d148959ff81817d5633bdaf60", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/brand-manifest.json": "891faf55b9a858456a5a6f592197410a35824d04efee425c92946b79f0609c33", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/brand-ref.json": "2602e9bb5fa9f1c767ff296557d056a5fcf86b4e6ec956f8f7fa950a0473b85c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/context.json": "935755f8e1fc58b959497926a6ccad99ac1758a759bc1154ac1e33c92f9a7c6c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/creative-asset.json": "e9ca4ec8a620024232f561f9a11acd31b8ce92e20e197f2e6986e672f11d5cf9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/creative-assignment.json": "b40954513806c5033d55c2390d6807861fd416067e617a6dd5624cfb3c2e001c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/creative-filters.json": "5790d16e69195d3832e64492568f0a81ddbeb373ce0935601f153dfe0f1e85c7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/creative-manifest.json": "5b7550a7d8c9e4cbe6f4dd7cb280dff60234c0975177c53e9821a978e39bf067", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/creative-policy.json": "be21bef6ec8f270ca3d68dc467e41e38e92c15e53e6efac15197a781ee1bf83a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/creative-variant.json": "9022e7b482dda4b5637d6c3238a09805481cf8e6fd85aef71ec17b6efd3b36a1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/data-provider-signal-selector.json": "dc04332241b8fc2320eaf48b7102d7f054082118e30f2e3313a4ad6251cb0d26", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/daypart-target.json": "d5075b942c8bb43e1938a7bcf396618630d33d5984de12aea4c2d90af5837cfa", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/delivery-forecast.json": "a9fa690698f2fa02c84613fab4b39addd4bd993ca611a1a5f62aff71263abfd0", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/delivery-metrics.json": "4664b0b3f078f55800cd68a5d5492db825f3218bc838532e57ac59e759a82c8b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/deployment.json": "73da1bf54e3bf09da8d0ca9aa0989ed8555aa5a67d821a069f0e58b23fa66d2f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/destination.json": "86f0dc9b15fa752b23d29b082e38aabb7d5dad89f04fbd045b8bda2299343aa4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/error.json": "7c8c61f9fb23e9a880e0ec930fe0fc8c5d76c505d228b4d982d00e3931c19024", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/event-custom-data.json": "f80a2da1bb45e5a5750815b2be6e61243312e54987443db747e50457bc87c5a7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/event.json": "6cdb1fcddb87089bf16c9ab25a72566dcd1e9081aa2daed5509e91b23bd8f5ae", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/ext.json": "fb31c634048c743c5b7fe4369ac2bf630f2d2996e60c59b697ed127e202876a4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/forecast-point.json": "242c474b014f968c537729c0fee16f2dbbd43a825dd8686808a003ee7599ca9a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/forecast-range.json": "993dfcdbb8bb2fcff0d43e8dee91a4993edc6a5ed233664b29d5e5b596d78e32", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/format-id.json": "725b987c4003630efaf1caa01cebadcd566609037df425e7b76f01b441b91d51", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/format.json": "cb18e23e0a42798d9f69fb9fc8257c251c761a92a44960615997420a87d7beb1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/frequency-cap.json": "ce7d14d0252da12517801a0b5149b7d5d4c43614d87b7c7f1f84d4b590c1fbf4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/identifier.json": "a009266f5641a64b0fd2464aa749b402f7955e99cbe3819cb842c3fb9aafbaa4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/mcp-webhook-payload.json": "c7b47bcf31e790110ef9c46b04b2f4baf9ca4ce5d77bd98ae454e05f109caf98", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/measurement.json": "27c57afd5c90e089803ff2e082a619d8ee8d160c7a6fc3379081d74b6653a012", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/media-buy-features.json": "d1286343cca262c207d21d5352cb792add0e74f65f79746a86f2e1ddcac4ead7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/media-buy.json": "3bcba672b4016171bbda032a7cadd4835d40bb75ba8096d43bb775b4638da65d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/offering.json": "f40ebe5ea30d1e881531da3c760d9d2329a221ac69bf50ed06d9634f4d8724ab", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/optimization-goal.json": "2f3de1f5c8f8d65b9df0be413a5a3e4f4a819baed4b6b901d19925d5d707d9fc", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/package.json": "899678c14253633650ad614fd5d828c16ed3253f207056b62eabfe4f3c0d452a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/pagination-request.json": "2ba731afd3ba583f3e2a0dd4bcc0249e9b32ccdce2645caebc90bf765bb996f9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/pagination-response.json": "3c5893c85521b6e8a96b7c875ab57b3315e9c9b7e5256a2857e0ff167d754609", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/performance-feedback.json": "9455c5d1d56e4f8e543c61c3c617db4a9abc009b10d656d90500bcddc515b0a8", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/placement.json": "a268fad0d944f47e6a0ea3e3a4d226535a51da3068ff9024c08723d7d6a7cde4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/pricing-option.json": "d1adbdeec14ab27486971983168ae16892b98ab1ddaf052769e767b6ddeb475b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/product-allocation.json": "17ff7cc79121263955c1a84371e0a47c878e593e4a9f699c858aa57f4ecac3d2", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/product-filters.json": "bf157bff7ccf3dba692bfa9e72091393fd451aec6f71366d852b2f26a3b0ea41", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/product.json": "a9c7c889ac59d30ec07de941b309a9f510f74901ced290e55bb8007e505e2140", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/promoted-offerings.json": "0cff1f732adde4021134d5f81058ebef924aecb2b6d1ade174e7d740f551ab0b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/promoted-products.json": "41354d3ce9f87ec374bbaa7acd59a92b575ad25a9f9fe6a1ddf9cd5cea29617a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/property-id.json": "4e7610b76b584e75ca96a53b4240b4052a137a6d2f5b371fd60385795a6b31e7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/property-list-ref.json": "995a1a4b9b1420645be4ffbda32013f1dc9c93afa0055d17d58dc36ab5b2d32e", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/property-tag.json": "21792aa4515365acdc8e7d36680212fb5fda772712402ce24de06344b91cbd74", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/property.json": "3def786f559c6d04ca2de90a851d03cee2a3cffdaf15e7a682ad50ee8f96341f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/proposal.json": "203bc406885952e84dbb63fec885aebba0bb03b69970514da19b5a307708f19e", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/protocol-envelope.json": "ffaa6b010893d101258c29bb55daeda065ebe43de15d5aafe85421c4a5378b15", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/publisher-property-selector.json": "09a9d466d56eceba339330abb501fa9d8d7d85f4cba5105337d45b89dab54539", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/push-notification-config.json": "93e3e0bf823c15c6be150f616f2546cfc6cd8c079522060980812d44dc7212cb", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/reporting-capabilities.json": "b1e567189cd5c40facce887253a14210b72dfe8147e07901bb53cbed0e6eef22", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/reporting-webhook.json": "25d8f6b9b48883f667efb61be097f0d3f20638ecef184e744b17963a676664a9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/asset-requirements.json": "a7c9a7db8b64b6055208fa210f7eaf8f4a4b5958cc3ed28259e26b03416846ca", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/audio-asset-requirements.json": "dc8a8ce2d6758ca3c0a15b1f59c4a7ece95501af009c2b9672200b3f8014c9d4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/css-asset-requirements.json": "326d263531f43268942c10cf59d9649c78f0ee1129eaddba23262acc9285cd1b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/daast-asset-requirements.json": "f19e37622172a7b02ec217c3e50797f8a186ff72c36bd2460da53887eb40ad92", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/html-asset-requirements.json": "d4ec4244410ad1ac8ac5fbc4e60d1b3bd9443536d5826555648199d6d7d27e69", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/image-asset-requirements.json": "a7e198ccddd75cd5b5653619401a883706ba078e8d06df05cfb37cdd7620ced7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/javascript-asset-requirements.json": "9475fb00ccf27f7a29e41aa573716377d4c5241057ad463e894d1b8644847eee", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/markdown-asset-requirements.json": "c663ddd5eafd54120b0434c3bfe8fd60dbdfb843f381925f3ce70a770b85445f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/promoted-offerings-asset-requirements.json": "00fe7eb3a4ca05aa14272597607e1d7dcdcbbf4fdba7cc9226edf461163d7d45", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/text-asset-requirements.json": "67925cde2f775183b4226368d37904b8a69597d16a819ecea6e218ccaa59d8de", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/url-asset-requirements.json": "c0f819d87cbc34f3760c9420713e6d8795b5d307a3c939cb6607c7d4f64cfc21", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/vast-asset-requirements.json": "18c4aca520e2194b0630daffa9c72ca14d8d567bc7b60f3413d6c23fafa28d66", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/video-asset-requirements.json": "2e598c7b747eb666cddd14b1a282bb040d942332ea355308ce9eb1888b62fc67", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/requirements/webhook-asset-requirements.json": "3349baa6cfcd9f5ebfa4d223e36f3ea8be42730644a6a6451f9c77e70656c195", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/response.json": "53c47fce04dae328dec77c466ad7c59eb5ec0d17fb38a59aaa95af9f14125888", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/signal-definition.json": "9c9d469228ffa667449d9c560d5c6f819e0825c1bba03b704b4acff3f9c1b6fb", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/signal-filters.json": "9259289d677c7399c2c59b19d6cf35f69ee198fba770c4f25162fc4dd9b015d8", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/signal-id.json": "908b091e64392bb3ac29f1e7d23b1a2f8c9993bf26cbd1240f49b43f6a451b16", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/signal-targeting.json": "e6aae4b3089f69be600c1f93bac79e45a18fc5d0381d8c3f12a159d797124f9d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/start-timing.json": "edaacae3d15f271a6b04cfccf3677864800aed339c9a7c018578e78355c8fd87", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/sub-asset.json": "970f1988a60601e9d529014efa3909900595011766653d1475b5a58d0fb448f7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/targeting.json": "d693a7af405fd69f4ad2d7b7826e896d58d8654fb0affbe1eb794e1da690d26c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/core/user-match.json": "d5234e1e0f24764e1f19d087cfeb609cdecd10b570dfebd6f525f5629e3d09df", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/asset-types/index.json": "40e0b08a1a04b09eeaf678c24ffc5cd3975789f20d0cb590227ca1ca5e2f4e2d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/get-creative-delivery-request.json": "b49f7a504c5c9d14d89e512bc242c32b1f910e2d02ffd7a874c51dc7c96e3ec5", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/get-creative-delivery-response.json": "c6daeecb90d8e95dbfcd07b8b61ec5a1c3a82b8dad3c48b9b1ecac49cf10ce86", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/list-creative-formats-request.json": "619cc1490ec0b2c4a89f69cb5f8950e0ce83f6768153ba03dcbfd0be68375c61", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/list-creative-formats-response.json": "20bcbafd5f64964d6fcfc244151f110619ec93bddc63c6685a103d21b57e873c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/preview-creative-request.json": "d41a95b88259e52836f54ee705b19e583c0947f64d30d0ca78624007e2110d8a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/preview-creative-response.json": "c877feedb1975124e8aedc7b854f0cd7b042902d778b8d277637c9372cca4bad", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/creative/preview-render.json": "5de3363bd0106ed59d22767e9b749484e05b642ae7a29581a4f5fd7ed7735ad6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/action-source.json": "143e5085fffdb7040d2e20eb19795444bc26f40efbc5b0740c806375f55cfe1b", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/adcp-domain.json": "1e601b909ba7eb2c1a1db0cbc2109683f63860af18a49bc5286a46768ee2fba3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/age-verification-method.json": "d39f4ce69dfbfb0678ae0f9ab1b3b7d379ba0e26641485f9ffc7026248db2a42", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/asset-content-type.json": "7eb19c59c4ad934ecec5f04ced811205606bf1d4a5e6dcf665018d607a392c18", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/attribution-model.json": "4f4d0e95bb7f91f097e5da5c05724487f5a5947e62f9af682fb3e73ea636f745", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/auth-scheme.json": "3eb4e56c21c07d43e6007d62d29986a4690ac1e22939a80d052e214cec0a41b8", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/available-metric.json": "3397878af02c91455d09953b521b05881018f484f7550c4f533ae40120a6eeb0", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/channels.json": "fdf7aea9c4268f757e2e413863c5fc29705bf8fe74ee5bdaa0249465def14d31", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/co-branding-requirement.json": "0611c0ec5d999d075d843f6bd02990a76d7866ce7b2a60575258c1848a5f4ba8", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/creative-action.json": "6344ffe2d108d77d063520d4958e16a79fc92405d03141ab0ea03a13b587d543", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/creative-agent-capability.json": "1a799ecc889825709d1fa3f5fcbb53d1cfcf69e05afabaa947d33dc9a69e45b3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/creative-sort-field.json": "da18c7dd55b893a2da3381d1fe201b033169e0b09f11c0f81ea4b344e27bbf97", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/creative-status.json": "f83f6473a6b7b269e3a39b3892b39177f22811fa0fc7d24dd4b1ea69a83054f9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/daast-tracking-event.json": "6d33d049ac8606466e2d106d28eaa76893a843c419aceb0f06a655a97fb257cb", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/daast-version.json": "09d20e4c991e8bf46650d66de3d0b0c53399998effec98a26f318ecdc0161d96", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/day-of-week.json": "04b4f1e22b622498f6a3cc97b8c186f1067bfe50446f4c8869b3d0f6fe6a09e5", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/delivery-type.json": "f955889137400b8896252715fd569eecb390a2dde710323ff305aac5ae070c31", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/demographic-system.json": "b7ccc23c443e751689c94608ccf35653503475ceeac30ddc697609de6b898a8a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/device-platform.json": "325ac47331d9da5a3918571fa6418c795090088e0b44d00919e41ade297e4484", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/dimension-unit.json": "7ae8c736729ad9c52254a09b58aeecf3b28d63a72a4f229494e093c70861b1ca", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/event-type.json": "278283a8abd0a6173d8909d3d2fffd8539f6b506647ca049b33dc89cd1380be0", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/feed-format.json": "0e2c6e03f1ca7fc6c63ea6d33047522337d864de2fb261bda7d30397a085ff79", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/feedback-source.json": "77579d0de19322bf8e185cc460d4346791d616b527e5cd9e96e554a1b3c967d3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/forecast-method.json": "8386c488664257f7c3ea32b055a8d9874d566e9f39750d97e981577fb8ca5246", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/forecast-range-unit.json": "beb74df7d8a38548943a6f07c158d09291b3282fdf3cc99abf173aa484381d22", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/forecastable-metric.json": "c8c500dadc284e8d77c44e2a3d601e62ac978158917a11a3c1f516146151acfd", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/format-category.json": "734f6e48570f80293dd91c8670a9c80b7043b5c7ce4fa1da9ef47fe60ef88166", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/format-id-parameter.json": "e7a7b038a9406b868d03507f136d1bcc0ad487955949d7472ff81aa6d323d0a3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/frequency-cap-scope.json": "0db0dd9682c1f3877c6f875c3dee248f96f6095b8805f37530661711091715ed", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/geo-level.json": "a69e4b2d0b2b7baec6d2e408c22b65a3d66212690e3cd9e48a44376872fdfc76", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/history-entry-type.json": "619231e04e3448de80f2df664ee0733bd6ad4cb9ff6d01b29a403b11d0a717b5", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/http-method.json": "9eba1ff180720f7c69a8b5d7fc900b0e4f819788b12c879d1cfb9ddf02e0fd7e", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/identifier-types.json": "5f7574b684caa5ae6038bdaf5428551fc60ac763360daddefcc7f6f809fd4289", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/javascript-module-type.json": "eecfc810c91f3485a8ae016f5b6d4430e59f2aefc7bca3bb0419c3b56dc79145", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/landing-page-requirement.json": "eab9c0417c7cdcd33522d2fccad63da767989f09816862664938c206f543ccec", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/markdown-flavor.json": "a73c5308d06ae5049a773a870a47970038d685372b61976d408731f3949ee65d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/media-buy-status.json": "40aa205376ae88feec7441f68dc717e347c4f36dfafc230108db9c4def11316d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/metric-type.json": "769794a5686984107a24dc15dbdc7c9bae63a7ad6bb7971d17d772eb976b300e", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/metro-system.json": "e11d52d7dc9590224bcb00fc3005dabc46ad757c7467a81c70d6f8af0e9419ac", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/notification-type.json": "a6b9e26d739bc1580e0a535176be37142e9ed020990a3469dd7cae3ef1053857", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/pacing.json": "5c1bc131facfd37ed13518d6afbc6774fa7c21a5f5026ba2e5fa67992c5854c6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/postal-system.json": "07fe85ef6e4fd9f6569f3ece3a9b21b5c8984058414049afe3190006ef99dadf", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/preview-output-format.json": "88f74df2c1d6a530f2b0afbb948fb4d0296811ca1262a0aea05aed91c9b08d91", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/pricing-model.json": "6b318cec8505d2b861b808a7b814d9b305af58c7d78d6792fd66b43034a90efb", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/property-type.json": "0acc93bb16b4253bb32329fd0270f8608be86f84e6b4187a4568b4358366a664", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/publisher-identifier-types.json": "7a62110bdee0914e2cd727fa3968f44be7ed54b1c26b9fac7facfeb8be5890ed", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/reach-unit.json": "0ad9780474bafac6dd4cc607364962757680efdaaf059e9ca9633e33b0b66a01", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/reporting-frequency.json": "8092570469ba084e8e7f6d2921ab1709755813422d042abf2e8c944534c8dee3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/signal-catalog-type.json": "4b5f93185289cb5730fec94759ac6cb2091237fd10db5d9347c7bb0e31ac2c97", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/signal-source.json": "e089f0d215fd4d3d98ab9d021283b5fa0ce8081b35c7c2a585b8131a9d0e03c9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/signal-value-type.json": "b3e14beb72c231eb2927cdcc6450f879f8f95fe514036704db38dca8df103031", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/sort-direction.json": "439d0f464f73436b95b9d5d79356923bfeee1a6928a1be15ee01573ac4f987d1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/task-status.json": "b181c42b2904062965391b6af97fcc00f182278e0aa314fe0cdbbe525b76ef74", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/task-type.json": "963532ba6e0a127d79793da0d1ede663a2784c09ed6459d24668259f7f3ffeff", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/uid-type.json": "9ffc9840ffaac682ef3d08b36a115b24c56b86f73f921cb58598aa13ef72c4c5", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/universal-macro.json": "430c884a09f62e827bbbc25f126d5689443f0420f873c89ca8bad7881a37d94f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/update-frequency.json": "0366d6b07e8b82dbaa6acf7d9c09453314771d92f5e47a8d36dbf3320708dd71", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/url-asset-type.json": "66432d9046cf081df43444a2bcbb278dce3d55bc470475c37dc15b8c713cdcbc", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/validation-mode.json": "c3c243e96ede7005ae9cbc36f8abec471a930ee0083b8ed5512b7beba614b91f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/vast-tracking-event.json": "0a25b49721d86e10a08c5bf9c81aa8d4dded859e5a38c1ddbe99aac9bb2c56a6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/vast-version.json": "02cc7a422a287251ef0481527d4a885d391e6b924a4180b6172a4262008acaf4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/wcag-level.json": "b9cd9b169bce3265154e8e7e16cd0e8df71e47f1c075e865ef3b52d69de290b4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/webhook-response-type.json": "44951eb3f55c1efc3c5390c7f360c9df7f57faefcba6dba3c89447af052845fa", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/enums/webhook-security-method.json": "44c44d2deaae78886d617636af4ee19a6d21556de4d09ebd4fb83dbb332d2c68", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/extensions/extension-meta.json": "96653ac32a37fcab33ba562c62f09af7362c81cca7f95fa181499dd9d3b8eabe", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/extensions/index.json": "11a8a4374b730d2ca0da0dfe0e8097f8e076f28826517f42bf88a6b780ae207d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/build-creative-request.json": "1441377e6d792e4c2fe7112c2d8a25b02bfe736eb0c2f8077cf48db324dd4265", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/build-creative-response.json": "e014e0a3bed6528e37d56403dacf0d97b7a97b162a25fd419e768f40bcb6bafa", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/create-media-buy-async-response-input-required.json": "c51d751c5349e1b2d4bb41b46463a171560fd886f363f95a5bdef3a4ac1a89a3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/create-media-buy-async-response-submitted.json": "27f8f65253d4c5820c8bad09008b16b4779b4ffa53a81a50f3b48b69bfaebb84", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/create-media-buy-async-response-working.json": "06ad0917dc43f2c7abf36bb5956f3e668dd2e25947a5dda9a252abd3310ca486", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/create-media-buy-request.json": "12f7b68e5ac826ae82f3256bc17885e600cf0afb8cbe7a3b2d10e14bc71e73f4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/create-media-buy-response.json": "5145c8bd2cb868d7c114073f4feecd71f5e87feae70a9a5fb23dc00d0c36826c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/get-media-buy-delivery-request.json": "efd32796d2b1f80168b99adf04e97c2d584e52441bd5d89d05f375b4c3d79dae", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/get-media-buy-delivery-response.json": "bfb168fa2ba0d2de9ed74dbdab7eea22091325d53790843dbc23bd1477ea7c1e", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/get-products-async-response-input-required.json": "f6c47fdafa533c16c628447a3a25020f488bb81d4086f209e7cd9b0823dad0af", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/get-products-async-response-submitted.json": "1575da225e8cf99d8101f4c63c93863439175eabd1429eb72da985b558f2589e", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/get-products-async-response-working.json": "f0a7fd7fa521594ff9f30921d0bf0819dd8a170af3dcf4d6d82404d9d2730291", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/get-products-request.json": "bb499a4e6aac1be0409f21e8c6d9f0b4585ae03163c12790386772ebbec3c3e3", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/get-products-response.json": "f3047328e09c0eac5f2587d46ae9dc79cea54275e3b474a83d4690b5494a22e1", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/list-creative-formats-request.json": "313aa5bdd8ff5fa2a2252683b027c08f1e6ac9e55d90df5426d8390614b78bdf", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/list-creative-formats-response.json": "e21445b9c4775e4f54870dd56f0d0f964b5a40ff6db3e41037ec3a783dacd315", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/list-creatives-request.json": "e9848da6de6011c9e61a323d08f3bdd79dc03209dc8226e6e915017e96633dd2", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/list-creatives-response.json": "08cf50af48d378fd7da44e60e417d5e0c0cb193252a5440a9d117b3534f62b40", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/log-event-request.json": "012a76dc1e61b0fa10d27b650b28697ffb5d69a6059ad4c5a5c38346eb8777c9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/log-event-response.json": "78dd5694da967425ac99775492a813d2d43227ca30cc4540e68c335d76bb7472", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/package-request.json": "c5bd475444f506e245fccaa1d8add665395383cc1c0324dbdbe87864765b6a61", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/package-update.json": "a68aaf095fe1d7b5764bba3d40f955076be403061e57b1fc4528aba6fb88e51c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/provide-performance-feedback-request.json": "34ded9261c702de8dd164b8cffa06d3805f24272e5b3ff4e650aec06b60bf725", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/provide-performance-feedback-response.json": "67a9c744824be92b94d50a8dbdd6fb647e7f63c36401e94aa735914ea3728fdb", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/sync-creatives-async-response-input-required.json": "12d01d4aa4cefbe2dfd914b07a270d24848f33fad3f3793337fb961d8be3e7fe", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/sync-creatives-async-response-submitted.json": "36b17169807518d2a6927bb3f9e2ce32ef4311bcd3a52ba5d58303ff633a557a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/sync-creatives-async-response-working.json": "51b35b92da710a6d2c3de99aaa8556f4fcf453be2b464aa7e525926a75858e36", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/sync-creatives-request.json": "856694153fa58de5eaf0762f3fca5beceae4aca0287df3963de54ea4490d763a", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/sync-creatives-response.json": "731c14b4f8dcdd082139235f038026ab2e2cf70fd47c47b1fc12cddc443c1c30", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/sync-event-sources-request.json": "1bcf47a2e03f73fd32106d9b463e9361c705ce043b30bad23d74dd078bb04384", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/sync-event-sources-response.json": "ff7adea09875e4db5ea9a6d10c1ee8a7c055dd7debae8915f5c4672b3cba86aa", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/update-media-buy-async-response-input-required.json": "4da8b3db2b7db8008e037d8e3465b427e0837ac5d4a823cf5529fb8e54cba0b8", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/update-media-buy-async-response-submitted.json": "6986d66652fc9cba34014d140ded67d92719e94ca296be940991900061904771", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/update-media-buy-async-response-working.json": "6b06ff7cd4349ceb366ed029581e061f829cb1f175023c71bdbab586f36eaa80", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/update-media-buy-request.json": "d5876996aa827e284c829456e7dee77bf735821165100b91f5a0c6726b924cb5", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/media-buy/update-media-buy-response.json": "7d198d3ea9d6123bd3497f2a55d25040f37a4ec7f9f28ca97530b76ed20f3243", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/cpa-option.json": "9a4ec8093d097a54baa405c05d96ed01c7b22123ed54508651fa4275acc05c78", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/cpc-option.json": "ce6041ec41dffa2581ad54aa8e5a39867fa2d666f7f76edbfeb91e0e85da8cb6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/cpcv-option.json": "2dd47be339cd28b1481270b7872d1a23d32066ffe722d29c68dfb6fe2925d71d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/cpm-option.json": "a944893e959bbff6cbf16e37cfbcea22a2bf355c17f60d47514e36b023a5e836", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/cpp-option.json": "023fb7b63a07a84a2919cc43e943bb6b6f60a756e77b0765d5d778e35ba176b9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/cpv-option.json": "4e5f0ca59a587818aeecc0aac16561eb24df5a2f5a6405defde3aeecee8a4184", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/flat-rate-option.json": "59c67859dac0636e901400085bd26a2a42c779f26521901a5a78878218ef72f4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/price-guidance.json": "cb5d6eb39e3698760a6b1550d97bc6a9deb55cca024c95620de1e045b0157b0f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/time-option.json": "713a0fcff664d9872e8ff81471fa863d06246aad9c6d0eddbceeead6c4376bd0", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/pricing-options/vcpm-option.json": "a279ff884544fe5124e1c175a7aa4a7ebd494a039ba0699d19f459dcd7212f25", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/base-property-source.json": "b0c9c8b323f5e32760a01dcf58d7504469fcde1842f39a4fc94379808ce136c9", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/create-property-list-request.json": "24ef0467ef7c50b5bbd7a08293ace076146d35960dc2134cf38a7390e35f96f6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/create-property-list-response.json": "867d8ec00cee5a3a54facb7b9ddd4717ee7c7487106260971d72b16feee33297", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/delete-property-list-request.json": "db1138f51d7b4eddf04a7999fdad6a53f4de374a5dfe554fb8242ef1e3814aa7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/delete-property-list-response.json": "b46380715ea660fd452280198b594daf8030e6acf9fde23c4b39993a16314751", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/feature-requirement.json": "287e88008b921be55744b22fff51c8919acc910fcd7f35df6bb073642cc551e8", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/get-property-list-request.json": "88a92b3e936b088a6a97035b964aac9127428900e5dce387bb114bf82b00cc29", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/get-property-list-response.json": "9faa9586fc5a3e44b774bf5b4de93d89cbff461e7714718d0c0baad9c044721f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/list-property-lists-request.json": "fb64c8f0bc2925e9d8107448fdc53fa271b9c051f108dba66f3f4f0a92413668", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/list-property-lists-response.json": "326c9dc839817f17db66b0a908715ba8c02d74190b2cf4e24d77c23c394f440f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/property-error.json": "a36fae0f18a37bacbb84c4dbe1b882766905502fbc88ef95e3bc517f7570a549", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/property-feature-definition.json": "779f0b9f272822e52af7d302a0b7dc517cd414cba17a5008334f927d735bd3ce", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/property-feature.json": "d748c8123b8eb7d6b1ee715dec3a5402f2496ecd4fa953e4389486048a2a5c8d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/property-list-changed-webhook.json": "2af28fc2cee066224aeede50bc38e4d1f98ca571deec24eb45469ce2862fecf7", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/property-list-filters.json": "b95fdf9d1b2511c507b246ea5942ea1603989150082f498316a4ea17007c083c", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/property-list.json": "55fec81a94b3975c5fa666ee827a6a79ca67b6847b6f06758ddee58d619d8708", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/update-property-list-request.json": "5bfef18fcc3125da0866d3e86246d7bf0e42b2ddd25be860c028df68550e3ded", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/property/update-property-list-response.json": "169adc9fd44efa0b88883bdbd8649e25a2d5ccb03e00311fc793dc8ba734ddb4", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/protocol/get-adcp-capabilities-request.json": "1f761db4aa1c358861ae6ba25d53ea2ba1332a493f0da8afb423ecfcb6cba568", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/protocol/get-adcp-capabilities-response.json": "cebae59ec79eaad673624ab31a41caea4fba460407bfec9efdafdfe6cbb50b4e", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/signals/activate-signal-request.json": "25aeba1b24ca80ce83e9cbf38c0245ce387baa13f29a684c0d20bd927e2f0736", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/signals/activate-signal-response.json": "c0f9e2de289fd7c767107b1495ba0c339b1ee6fa0711fe735ee6cf82f8314be8", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/signals/get-signals-request.json": "ba205285a00e353b27ecec1a23dd651922e11c50b7f890921d914c6d280ce9cd", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/signals/get-signals-response.json": "2d3b3dd345b170f4b758dcdaf77b3cc636eab8e4ec3192f5632b5c660b9e781f", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-capabilities.json": "5372327ab157be85d6ab7b6dfb954cc35c22af3ed8848022d2cdfe9980ee9927", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-get-offering-request.json": "a87fb0c42a82b160e1a31ddc9fa13454c21bd941848f30e542999fd2dfc2de0d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-get-offering-response.json": "e23688658ea6fec7fb2ab480e00912c5a4e254b3e7973c146ce8d0da10277748", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-identity.json": "757bf9f365bd4a90a1ee9a8b96381a1fd84c359a83bb8e06f27e9b23099584c5", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-initiate-session-request.json": "f58d1a0d0d07f9bc91a6dc701a0ae7dff327ad82ef3f370444cd1662ce906227", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-initiate-session-response.json": "21923207338de5fef3746f41f0ddaa435c076751c35173d242fe6add8b65cb9d", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-send-message-request.json": "ec2655dbede80d68e589961ff690a5113867b5ec9d84e4fcab0a05bd472fc8f6", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-send-message-response.json": "958cc5aee0a1eb9eb552ade1e6dc2153a672d03d87179000065415ca6b8ce333", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-terminate-session-request.json": "a7b234e2055e17fec9e4cbf0487707cf009ca74e76ded414b269888543b44507", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-terminate-session-response.json": "de760ffbb48ce38b3be816b405292150cc4de85ce284bbabaae4b87117ef5974", - "https://adcontextprotocol.org/schemas/3.0.0-beta.3/sponsored-intelligence/si-ui-element.json": "c151a48cbcfc5fbbf8d796f113cc89fbfbb57c714a9308b6158ac68e747c126b" + "https://adcontextprotocol.org/schemas/latest/index.json": "03778df96cc96cf6c3f5a1100ebddb876c427997eb8a9ec178eac5a004fdb81f", + "https://adcontextprotocol.org/schemas/latest/a2ui/component.json": "1ff7f295b03519313584895022e5add7556d275f99333a987301e11c9ccfb3bd", + "https://adcontextprotocol.org/schemas/latest/a2ui/surface.json": "7bd19b850a819c6e25f55f37645eeb92a479ece0050ad826fd7f2fbb979ce80c", + "https://adcontextprotocol.org/schemas/latest/account/list-accounts-request.json": "d961b9e44c0c591e26a75f5fcbb97bada2910c57c89006a95ca0c353323bea05", + "https://adcontextprotocol.org/schemas/latest/account/list-accounts-response.json": "25b0191d62b9aa14181d70d5bf41014432f76a1f17754548f9f4eedebc43ca49", + "https://adcontextprotocol.org/schemas/latest/account/sync-accounts-request.json": "60877d20fa2f32a8f083c13d5396f25f9357c430a34764bd72a5b2a1b29281d8", + "https://adcontextprotocol.org/schemas/latest/account/sync-accounts-response.json": "bb0b4b03723250b0f3a0933cbd8aa59a5e28fad33e1c800b039322ea34571353", + "https://adcontextprotocol.org/schemas/latest/adagents.json": "c9608e07f49ccedc7420d1f0d205a92dd78cbfed662de606d458cb3e5c46efea", + "https://adcontextprotocol.org/schemas/latest/brand.json": "0cb68a8f1683c0af3e28fb1e48f602832e78321d1c575504be62997991003dfc", + "https://adcontextprotocol.org/schemas/latest/content-standards/artifact-webhook-payload.json": "a5ddff12ff1d6316636919bc87359980512e63ff688d4b742628ab06b91b537b", + "https://adcontextprotocol.org/schemas/latest/content-standards/artifact.json": "b499571575b8e0f11b5c21dd32189fd19191d32a795cff225165fdfd0092917b", + "https://adcontextprotocol.org/schemas/latest/content-standards/calibrate-content-request.json": "fee8b02f136fdbcbe9ca35879d71f19cf37349de9b047e1c6e7e65b91b23bc3c", + "https://adcontextprotocol.org/schemas/latest/content-standards/calibrate-content-response.json": "55b76ae2eb728abc8b5dd9d5d2f3af25a4dc6c31c06d8a76db5d4544e6001ecd", + "https://adcontextprotocol.org/schemas/latest/content-standards/content-standards.json": "05c7e4528eab11b1a010d46fb6c13bb54d40dd088ed202d7d74bf55fb40f1465", + "https://adcontextprotocol.org/schemas/latest/content-standards/create-content-standards-request.json": "1adc8e7387b215b22e822fcbd13fe4775eb4ac340cf6200de77afaae41a4889d", + "https://adcontextprotocol.org/schemas/latest/content-standards/create-content-standards-response.json": "9c5cf7b12680c14ce13542d0c032f7b5135a0546a917147aac8633bd43618ec5", + "https://adcontextprotocol.org/schemas/latest/content-standards/get-content-standards-request.json": "abe28cf4158bfa4f4333734639e62fd4d3057ab9fbc8eed0e121e51ac6962004", + "https://adcontextprotocol.org/schemas/latest/content-standards/get-content-standards-response.json": "2b857288ce95461fd5e278fe27d6a21dbb06c442ee2a8f41db2530e547280991", + "https://adcontextprotocol.org/schemas/latest/content-standards/get-media-buy-artifacts-request.json": "515787e0412da0b06924a11562b5428742b544af4ab585ba057f49c1dddefb16", + "https://adcontextprotocol.org/schemas/latest/content-standards/get-media-buy-artifacts-response.json": "b03bcecc5c2354ec1678cd61c71ad38ece2abb0f52e2047ae86e599738c9cf43", + "https://adcontextprotocol.org/schemas/latest/content-standards/list-content-standards-request.json": "9fab6d60550d4e229ac1acc69658f8718cf34a9afb14f5b7c3f22076432bec7c", + "https://adcontextprotocol.org/schemas/latest/content-standards/list-content-standards-response.json": "2b24793b3196d2da1896d10e5298fcce43c72486859ae47fe0cd6b0ebedebf3d", + "https://adcontextprotocol.org/schemas/latest/content-standards/update-content-standards-request.json": "934163efa243f33bded9b18b458e6515161c5eb65ea82600713b1c319c8a4402", + "https://adcontextprotocol.org/schemas/latest/content-standards/update-content-standards-response.json": "68b2307f5a152df438f8b406873292947d477cd1d8e392a074ac5b7f61dfd190", + "https://adcontextprotocol.org/schemas/latest/content-standards/validate-content-delivery-request.json": "560e1251702f3c09ea5886ff730fb4c88d53a2e6a8b4c9804bfa60ac9ad5a800", + "https://adcontextprotocol.org/schemas/latest/content-standards/validate-content-delivery-response.json": "a3223d796114054b90a67ebff460286a5231f956cfbbfae2398fef518dfe3b55", + "https://adcontextprotocol.org/schemas/latest/core/account.json": "b39e79b4a764d2e22105d08c0c9d99d7e92fa5209cbb6b7ca0b9c1bf05728dc2", + "https://adcontextprotocol.org/schemas/latest/core/activation-key.json": "a31fb82057c50037575304641bcb32999239a762d93c1b3f1c5f535678c898a6", + "https://adcontextprotocol.org/schemas/latest/core/assets/audio-asset.json": "3b90c8dc0c90abede1685c2cef9ea7516db4f9297800a0df648344bd4cef5399", + "https://adcontextprotocol.org/schemas/latest/core/assets/css-asset.json": "b37b137ff038e3b147d52fdcc221e6961fe3f3caeb62b4e3f2356cb448ed7500", + "https://adcontextprotocol.org/schemas/latest/core/assets/daast-asset.json": "d865304f3f316c4eb9e564d457b8778fac36806953beef61b8c7b6527289e142", + "https://adcontextprotocol.org/schemas/latest/core/assets/html-asset.json": "fb99f50038efecf5347542dd97e2a97ebb8d9af2fb5a16ea2fb27a8061295f42", + "https://adcontextprotocol.org/schemas/latest/core/assets/image-asset.json": "41619f4752377b258f3dac79597348f1cfab337420aa60160e167aa2cc6ea1a8", + "https://adcontextprotocol.org/schemas/latest/core/assets/javascript-asset.json": "bcef50ba306604f81bbeddef1023b598124f70fa6b0be11cb3702364d1ed247e", + "https://adcontextprotocol.org/schemas/latest/core/assets/text-asset.json": "b6a9bf1dd18971ff368d4d2d9c3796705e83c82898bb8672eda6a684149f42d4", + "https://adcontextprotocol.org/schemas/latest/core/assets/url-asset.json": "96ce5efde3ef98bba10d8ea9a43d8e778229b6bc1b44e5348e8380499e192fdc", + "https://adcontextprotocol.org/schemas/latest/core/assets/vast-asset.json": "8b55d5606f31aabfc0dc789f194f8854e9f917c244c3b8077eaebd1a26a111e7", + "https://adcontextprotocol.org/schemas/latest/core/assets/video-asset.json": "ade4514c505fba37670d51b4ecbddb1fe97c3f1e43ea9c59dbcb8b7602dd1237", + "https://adcontextprotocol.org/schemas/latest/core/assets/webhook-asset.json": "80cbe14067f4ba0155b32e089cfac4446230f64f9e4c189adafea97f1950fa7c", + "https://adcontextprotocol.org/schemas/latest/core/async-response-data.json": "b3e3e57e1a121067cdd6392265223a14b89ebb27220a18d822ffdeb09e7b7523", + "https://adcontextprotocol.org/schemas/latest/core/attribution-window.json": "cb09c3c758fbe16cd606f88fa8218105bbe03b02a659ca5a526799fc454ab7d9", + "https://adcontextprotocol.org/schemas/latest/core/brand-id.json": "dbfc3c2aed4d16ecbba3204200948437a2bb3c0b68c0117c3a8c93f3c0700d25", + "https://adcontextprotocol.org/schemas/latest/core/brand-ref.json": "b97b4c6a2c337078893cf4da6859e3ad4e14a950f643e306d9b308de4bc60ca3", + "https://adcontextprotocol.org/schemas/latest/core/context.json": "b5b5de9482d662c1eacfcfdfa53de672a047664e295940cb204f2d822d5eeb31", + "https://adcontextprotocol.org/schemas/latest/core/creative-asset.json": "690aad4582c719aa7b106c6af0a8b7a2b021575d1f0945c666c07cdaacd70a35", + "https://adcontextprotocol.org/schemas/latest/core/creative-assignment.json": "b62b9db75d306abe2e5f097aac1caaaeb214c0b22d37f58d63ba3f5c428f4f10", + "https://adcontextprotocol.org/schemas/latest/core/creative-brief-ref.json": "f664328da2c35e17c4ea72343ff471f51d6905f9414ae798ed186a7576f88d9c", + "https://adcontextprotocol.org/schemas/latest/core/creative-brief.json": "bbf2b432a7e8c63dd2649a6878d72753a219965906fd043c453acca691c49827", + "https://adcontextprotocol.org/schemas/latest/core/creative-filters.json": "62ce7508144cd1bf6c5e00fb618ceb98f2d4e30fd93c869cd661b530e81a9f8a", + "https://adcontextprotocol.org/schemas/latest/core/creative-manifest.json": "c38e0607bafeb45aae938eabe9a8159f78d368dc4187dbeddca0f0b5c391709a", + "https://adcontextprotocol.org/schemas/latest/core/creative-policy.json": "c63d0489e8d7423b49471b3ceeae3df6716e5313a842bdf881dfa4e1f3516e6c", + "https://adcontextprotocol.org/schemas/latest/core/creative-variant.json": "e240a67f4512db483ecdc8d57a3fde70fe5c65bc4d748e9cfe129fb079d1199f", + "https://adcontextprotocol.org/schemas/latest/core/data-provider-signal-selector.json": "58b09cd1288007e46d7ed45bb55d1c8743a9e358236a16586940311f5fd5fdd9", + "https://adcontextprotocol.org/schemas/latest/core/daypart-target.json": "63d103c751558a96ff308b0a54ecb3c4464880f81577cd87ab910713ec7d3156", + "https://adcontextprotocol.org/schemas/latest/core/delivery-forecast.json": "c6ac7da6a25ec81be6f8b09d466bc528a8c3ef207dd7c6f8ec2cceed5d8d8987", + "https://adcontextprotocol.org/schemas/latest/core/delivery-metrics.json": "3b271580ae8432ee21c2a2e909fff568cd424e5ed86fe0c1da667964c6f0e9c8", + "https://adcontextprotocol.org/schemas/latest/core/deployment.json": "5769c02297e584f761a55301732621e22f8166e9806a1933cb842c1be9902914", + "https://adcontextprotocol.org/schemas/latest/core/destination.json": "007880839e1d556972365ba1cd7076d081bbd6e6b9b0ba47147fc2748ce60d35", + "https://adcontextprotocol.org/schemas/latest/core/error.json": "97dadd80893ba1c3d371e7b3fefe33941e3b8e660e91d0e8e1517c5144851b1d", + "https://adcontextprotocol.org/schemas/latest/core/event-custom-data.json": "f50aee7ec70b300795df3e2e175d0f38f4d20e0b5513061d8c654d0f03cbcb9a", + "https://adcontextprotocol.org/schemas/latest/core/event.json": "e0c7caa7e23cc8ae493883caf52c9c012e5124acb295438158639b71e18a0b2b", + "https://adcontextprotocol.org/schemas/latest/core/ext.json": "0dc59d0cf5bcf97f9ce9ba635f977ec65b982e853cc0b05decb034cfb642f4b5", + "https://adcontextprotocol.org/schemas/latest/core/forecast-point.json": "a144ec1c7223c0f724baf260f1d47e43f909c1894c6319d4b5fa5e295a8b8dea", + "https://adcontextprotocol.org/schemas/latest/core/forecast-range.json": "831510663009ed73a328a015398130603a934031c963d973d70783bfa8beb44d", + "https://adcontextprotocol.org/schemas/latest/core/format-id.json": "529433d6d5ecac7514d85a0bdf80caf0a69a3c5c0f77a14932441a954a8ada15", + "https://adcontextprotocol.org/schemas/latest/core/format.json": "486369c331a22614dbd176ac2889aed051f83d34e74b87ce7a41cba40d7e461e", + "https://adcontextprotocol.org/schemas/latest/core/frequency-cap.json": "78e7d100a8f99c59d8190f487a868bac804a25a3797c06b8e668e782c0fe0dfb", + "https://adcontextprotocol.org/schemas/latest/core/identifier.json": "da78a993f66120ab06fbb6e4801a3806db72c6e5ad990c9565965b8c8b625fca", + "https://adcontextprotocol.org/schemas/latest/core/mcp-webhook-payload.json": "1dae520cb0c0564f4c647a5fba4cb8383897f28dcf72a2d046986684255f099e", + "https://adcontextprotocol.org/schemas/latest/core/measurement.json": "069685e5f69b28598a35e6887a289f82ea830c1d9c0a8c99e621d3c1a96c72fd", + "https://adcontextprotocol.org/schemas/latest/core/media-buy-features.json": "db640898fd8b2529345dc42ba65b6ec23d0e92b3372842d278595cdb710c74fe", + "https://adcontextprotocol.org/schemas/latest/core/media-buy.json": "0a1bf9824827773314e3bce015b71e1fca8c025ce069e0089954badffa7884d7", + "https://adcontextprotocol.org/schemas/latest/core/offering.json": "4a4e959938a191e74918ca48a506a90a0074584a7d1e6091b70ca35cd71e7657", + "https://adcontextprotocol.org/schemas/latest/core/optimization-goal.json": "b07f81fda0a47cb52d6842859e240fbfadd4a41b31316cac0b85163624885401", + "https://adcontextprotocol.org/schemas/latest/core/package.json": "20bae48eb97eb605334f65785b7e78c02928440e9bc5dfaa8024295e4eaf3ee3", + "https://adcontextprotocol.org/schemas/latest/core/pagination-request.json": "3cabe1c0ed60e531149578901518e9091e2c2c4345741cc8de37245def768006", + "https://adcontextprotocol.org/schemas/latest/core/pagination-response.json": "0279f24bdb2cfefd15d0f4c9faa4b5a59c39f1342ed0edfb8e66d8865b2395b6", + "https://adcontextprotocol.org/schemas/latest/core/performance-feedback.json": "63dec657c26dd2702d9051d151d428b97ce8ad427fea8571c571a8eb8f53d99c", + "https://adcontextprotocol.org/schemas/latest/core/placement.json": "2b5a7cd544e2ef14d03149b3fc47700ca4559604c5bc0c233bf44e2b2e8b50ca", + "https://adcontextprotocol.org/schemas/latest/core/pricing-option.json": "1c1591c8fb1a8ec4bf746e220cfdb05b87a058fe98b58600a04062e8cd1c6b18", + "https://adcontextprotocol.org/schemas/latest/core/product-allocation.json": "839db85911a6223fa1ddbabae93385de4dd55869800f2b71742dfeaeed676ebc", + "https://adcontextprotocol.org/schemas/latest/core/product-filters.json": "8fb007b7e1f9adacd7fda1bf85b39af8b5e8524f15f4a170211a607e3571aa0c", + "https://adcontextprotocol.org/schemas/latest/core/product.json": "2a3d58713984f1bba0d1a69d29375f1f6c3e0c730230c2dd5a6bc1368d4d3232", + "https://adcontextprotocol.org/schemas/latest/core/promoted-offerings.json": "6de3d6f347d0bf29045e53ca421915ec762ac3dfcced34aa9b8173ff29a010c4", + "https://adcontextprotocol.org/schemas/latest/core/promoted-products.json": "30d8add19c793d6abd69f6e9e90a9eb5520c8d54caf68ca952969d86b36f1b18", + "https://adcontextprotocol.org/schemas/latest/core/property-id.json": "16ff353402c03691a7290a0f7578a901b63a0f7e83567b8903c5c6f89e1fb6f0", + "https://adcontextprotocol.org/schemas/latest/core/property-list-ref.json": "50c908159f9d02bff2a3330ac1bdbe2a46c47649a3efbc0a8eb9f8118b3b70bc", + "https://adcontextprotocol.org/schemas/latest/core/property-tag.json": "6f2c35324ca6c5533a2c3d1a5837360c813a0905be68b11da7a46965ec37d59c", + "https://adcontextprotocol.org/schemas/latest/core/property.json": "f2057d364045fb833b9884a0902abdf1570719d4ab3bafd5649eb7b134d4911d", + "https://adcontextprotocol.org/schemas/latest/core/proposal.json": "855cd118a5b0aac6ed8f1628be49757348b0374c17596459aae8262b0dc8b4dd", + "https://adcontextprotocol.org/schemas/latest/core/protocol-envelope.json": "abaef42600786d78e1dfdc4986eb3ca7c3cd7f4955a2b8e9bfe27a4d9a58c3f0", + "https://adcontextprotocol.org/schemas/latest/core/publisher-property-selector.json": "2763ecac8effc1e27bf69d231968f25bad5ee2bb723ad1bf9c3da125d6b64099", + "https://adcontextprotocol.org/schemas/latest/core/push-notification-config.json": "64ed4db710d5a5346d6935e238d28ffaa4374dcff9d08e5d4283d4786dfe6de5", + "https://adcontextprotocol.org/schemas/latest/core/reference-asset.json": "76e1bed153f7bfcd1473401c7074a1679935491de8af1aa84530e44af48baecb", + "https://adcontextprotocol.org/schemas/latest/core/reporting-capabilities.json": "fca3c737c6214cd89fe95cd53acd7622e6f2951185ddf1c6fb869b1f23a245a6", + "https://adcontextprotocol.org/schemas/latest/core/reporting-webhook.json": "90e90d454334590670cfb881b14be00dd2a7fc134b0cc4494c79c6848fc2db1d", + "https://adcontextprotocol.org/schemas/latest/core/requirements/asset-requirements.json": "19b2e08cd8e6fea0abfe2da2a6df9114150d6a28ef3df6302a96f48e0fcac714", + "https://adcontextprotocol.org/schemas/latest/core/requirements/audio-asset-requirements.json": "bd73bc4f72429d9c9d8cf05ad6f97f5a345d0a43f9b791df1789a54a22f84be6", + "https://adcontextprotocol.org/schemas/latest/core/requirements/css-asset-requirements.json": "ec0722f9068095a8bdbed0178d84265875f9f52d5aebd957462fb02fd623c3fc", + "https://adcontextprotocol.org/schemas/latest/core/requirements/daast-asset-requirements.json": "d93404d9be0cf5b1bb8064beb674841394cfd6554d24efbc60ac1ad1cafac73c", + "https://adcontextprotocol.org/schemas/latest/core/requirements/html-asset-requirements.json": "0148d6d6ad4d0f23bb0db6e987642a4aaa0d12574d3decf653338935e80a6be7", + "https://adcontextprotocol.org/schemas/latest/core/requirements/image-asset-requirements.json": "66eb555df3951d87219bb40be98cca44aadaafa24fae8319e5edb09ad74f4528", + "https://adcontextprotocol.org/schemas/latest/core/requirements/javascript-asset-requirements.json": "0e2412d1587ae8d98735e9932c17a600753fcc78179381578ed89dc06c8402d3", + "https://adcontextprotocol.org/schemas/latest/core/requirements/markdown-asset-requirements.json": "4cb1c9b2fde8a7a7f982385579fd7d8b82bd85ef320711e31da41ba3db1ccd9c", + "https://adcontextprotocol.org/schemas/latest/core/requirements/promoted-offerings-asset-requirements.json": "567466fc50d8ae30e4473eef4ece8f27224e01619d8a405db6aa81a78b9f14be", + "https://adcontextprotocol.org/schemas/latest/core/requirements/text-asset-requirements.json": "164f0c6446409c78339354d34bfd864ff9c1a46f65974f31923c835241d984df", + "https://adcontextprotocol.org/schemas/latest/core/requirements/url-asset-requirements.json": "2d2a8657aad606ef5d51802b48786922c2c7d46b6f3e657109ae9a10e417bb54", + "https://adcontextprotocol.org/schemas/latest/core/requirements/vast-asset-requirements.json": "bf3f286a3829bf5920ad8ca311fd8caaa7cc2a02e904bb960222ee64b25b3b0f", + "https://adcontextprotocol.org/schemas/latest/core/requirements/video-asset-requirements.json": "a54590003a7d81018e91d4ef87d4644cbedc67c6f7f102007fdd6bff84d8be1e", + "https://adcontextprotocol.org/schemas/latest/core/requirements/webhook-asset-requirements.json": "0b6a9d602895cf6d12f8d70e4fd27d9914288ce09901149cc61dd3fbd3b347f1", + "https://adcontextprotocol.org/schemas/latest/core/response.json": "232e6fc35a8dec7e7ad0743cd9be807cd7143e32eeb162f830ab692347744967", + "https://adcontextprotocol.org/schemas/latest/core/signal-definition.json": "a44bce7c48946cb1aff0431170b940796afd36705c7bb0cf06f609e4b8705fac", + "https://adcontextprotocol.org/schemas/latest/core/signal-filters.json": "31748069e4127c516497cd2721f551a326e8f93b39c24dce2e393e677f90c044", + "https://adcontextprotocol.org/schemas/latest/core/signal-id.json": "f5bfd276c5eb7b3ce334e6681ebf67642ae28acf10d7527f0ee142a9c41a59dc", + "https://adcontextprotocol.org/schemas/latest/core/signal-targeting.json": "e80dcf066fe206808029174d0460139adc4c6ab9da70b82d0a29730efdab2a90", + "https://adcontextprotocol.org/schemas/latest/core/start-timing.json": "8e07e0469f434f3d3ba998e2b1fe58fc3dd097915e2d5e0c547cadfd5a469158", + "https://adcontextprotocol.org/schemas/latest/core/sub-asset.json": "c0293416fd0275afd5ef59bd68675ff8ea37e4d4ba8f3a13e375711529a6399a", + "https://adcontextprotocol.org/schemas/latest/core/targeting.json": "1e03c4763fcba90698bb4c5dd631ad52b25f589c77e3b21c7dc59314028928d8", + "https://adcontextprotocol.org/schemas/latest/core/user-match.json": "fe94aac841014b1f203583b0b4b4c736046867b4ff392ce9bd5b8f4625aaa452", + "https://adcontextprotocol.org/schemas/latest/creative/asset-types/index.json": "6393ba5e7c898ba0279ec1bae8a8985231a81241e2cbbdd47280cb3b83b716b3", + "https://adcontextprotocol.org/schemas/latest/creative/get-creative-delivery-request.json": "1dfca425f543af3ad29a997725812a605ed10b2fc3b8511fae9bc88e44c40b96", + "https://adcontextprotocol.org/schemas/latest/creative/get-creative-delivery-response.json": "ac4acc3a240ccf1197b54bf7aef076366222103b9fc3031fe8022633ce994db3", + "https://adcontextprotocol.org/schemas/latest/creative/list-creative-formats-request.json": "557d2c32a90e91afeb71f22210aea0369bc59951a41814f096e5a1a772c9ec31", + "https://adcontextprotocol.org/schemas/latest/creative/list-creative-formats-response.json": "3b5a07f923bcc243fc81c5f4725627b574b0d534de3b176fd972c2349364428d", + "https://adcontextprotocol.org/schemas/latest/creative/preview-creative-request.json": "8105cbfd4a021c41f7f1322daf75e8b9f6b7837e54295d701ad9c4ebb2c67263", + "https://adcontextprotocol.org/schemas/latest/creative/preview-creative-response.json": "ca9de195792f7beeddb5d7f6d148f8cf7693863706946aa44e3f6badd6c5e128", + "https://adcontextprotocol.org/schemas/latest/creative/preview-render.json": "b4837c5a4027d7034f90ddf914c2e5e1a90e4ba6ee76f68a1b622e8a6cf64fc3", + "https://adcontextprotocol.org/schemas/latest/enums/action-source.json": "02379d8670666e56afe09639030a13f672329f6717e687677619a48d20531e30", + "https://adcontextprotocol.org/schemas/latest/enums/adcp-domain.json": "ab0644259eb35ef366defd6e3e89f04087a7dde529d1dfd989a4ff5caa153b0e", + "https://adcontextprotocol.org/schemas/latest/enums/age-verification-method.json": "49a68dfd8bc550272f6e359de0cfc66a269687b2f0b2df4cdc802b23d702e719", + "https://adcontextprotocol.org/schemas/latest/enums/asset-content-type.json": "74414bc886efb8a52794da63cfbb873befd9d24c87d9293ac88008bd496dfafc", + "https://adcontextprotocol.org/schemas/latest/enums/attribution-model.json": "2b7cf8e2100e1a46cecf03f244c2d3a009934546b6c42d9c6ed77eb8ca100fae", + "https://adcontextprotocol.org/schemas/latest/enums/auth-scheme.json": "492732201479760e022e7e20461874312403dab836af0f45c1382fd7b59c8b17", + "https://adcontextprotocol.org/schemas/latest/enums/available-metric.json": "8b598a106359f0a64d9d629ac1b7c149d30456d55df3fe917c9200b177ed6fc6", + "https://adcontextprotocol.org/schemas/latest/enums/channels.json": "90cb43e6cca0dfb9f6424768a3a21d5200182eab0e998f50d2f3c91901fa3d22", + "https://adcontextprotocol.org/schemas/latest/enums/co-branding-requirement.json": "7d533d01abfc5b134985e4a4611547a8d88601f2ad3dae166d30483433a5af8e", + "https://adcontextprotocol.org/schemas/latest/enums/creative-action.json": "c8f56831b63d868ecdadb81787fbd9bda85f791387cc04d10a4f3f4774edf591", + "https://adcontextprotocol.org/schemas/latest/enums/creative-agent-capability.json": "c107eededf219f2f63e9325ba1c204c08f4bfe05b72ab90d4848308f771a9454", + "https://adcontextprotocol.org/schemas/latest/enums/creative-sort-field.json": "adc83644f01b9948aa436c79dc0701d878a876e185adf7808485772fbad5eb28", + "https://adcontextprotocol.org/schemas/latest/enums/creative-status.json": "d8c83590a233ec9e605c63ee8fa009bb7fb5b5336092e8bef0386f226cc0a5e3", + "https://adcontextprotocol.org/schemas/latest/enums/daast-tracking-event.json": "caec0a9b0852c26a43a41c52312a36007656f7104c5af276d1111dddca9e2041", + "https://adcontextprotocol.org/schemas/latest/enums/daast-version.json": "95b06e213a2279ad3db0cca8912324a7773bc90a28bd0a39c676f73dcc4c70e2", + "https://adcontextprotocol.org/schemas/latest/enums/day-of-week.json": "a21d7536885a975ae42c59fffa68b75aac48d790216c88edb3170b382959a16c", + "https://adcontextprotocol.org/schemas/latest/enums/delivery-type.json": "3934bfba9af3ef9469f73b85b15c61c058b79771e74ae7bc387afc95905feacc", + "https://adcontextprotocol.org/schemas/latest/enums/demographic-system.json": "690540c7a5d554e0b2ba60d3e07244e6f7d78e6c364e61ce7c0a951631472106", + "https://adcontextprotocol.org/schemas/latest/enums/device-platform.json": "4b9895324457519d04b076899c4e9f8e30f061a27f801685e23e3898b77e75a2", + "https://adcontextprotocol.org/schemas/latest/enums/dimension-unit.json": "405de49a9144c527466677ef3d3e5010b3cecea289f74b837958496da78045fb", + "https://adcontextprotocol.org/schemas/latest/enums/event-type.json": "a3a488d7985e1b67ccf086569d0b3a60d975d50e544862b735c3805ba10d7b91", + "https://adcontextprotocol.org/schemas/latest/enums/feed-format.json": "2147a55d3ab95d8108f6258d31c2ea3e37f32eef065af05236135600f4eb9c99", + "https://adcontextprotocol.org/schemas/latest/enums/feedback-source.json": "56283eec28ab10c8a11f09959c0f3dbef2b5bf02b7df84599343cb9fb0e69f78", + "https://adcontextprotocol.org/schemas/latest/enums/forecast-method.json": "692f2c79351023690c444532089f5ee9d60afb433eec60281cb0248c066f1212", + "https://adcontextprotocol.org/schemas/latest/enums/forecast-range-unit.json": "c7dd6d5908f42d1e910f2d38aae9de1189f65158d62eba044e811ce430620a44", + "https://adcontextprotocol.org/schemas/latest/enums/forecastable-metric.json": "cda32eedea286cd884d1dfea6674077b6293888a3d34a91c70875d3f2bd999f2", + "https://adcontextprotocol.org/schemas/latest/enums/format-category.json": "efeeb37272b115eae42b3436600c00d75c29e94763148206993f2942a2a8ed99", + "https://adcontextprotocol.org/schemas/latest/enums/format-id-parameter.json": "0783749a5ac1e2eff4cc523eec16e3a723e107b3718bd55e1bc671cf230b0a1f", + "https://adcontextprotocol.org/schemas/latest/enums/frequency-cap-scope.json": "3275a767cbde71235e7a23d0d775b5d58afb1859936393b04eb2c7c976ef2493", + "https://adcontextprotocol.org/schemas/latest/enums/geo-level.json": "e6b65de7e6699c4171eba799553a39f8d3bdc787242ef7bfa269b6f6d77a1bfa", + "https://adcontextprotocol.org/schemas/latest/enums/history-entry-type.json": "e77c87be1493e84d83ffb567113303e2b50baa1dbd8c1ea791e2e8822f2bbf64", + "https://adcontextprotocol.org/schemas/latest/enums/http-method.json": "75c12b6e8868b0248841bbf8e666fd097308276f59a2c8f809fa279a88c06188", + "https://adcontextprotocol.org/schemas/latest/enums/identifier-types.json": "73190ea41c388af5b6b9c56358c4bce893b0f7cf61bc5062647f9987755451ed", + "https://adcontextprotocol.org/schemas/latest/enums/javascript-module-type.json": "da4746acdce608ce9497f59e7fdbc97a649367e55aebe4b9675feb3176e8525e", + "https://adcontextprotocol.org/schemas/latest/enums/landing-page-requirement.json": "5a09b76855c541b23ccf1aaa8ea87e77203d358b5c01c1b255722f21ac6327a4", + "https://adcontextprotocol.org/schemas/latest/enums/markdown-flavor.json": "df8836754968fb1c02fc7725aa1bce56e315c4cec11515a19058b5d6a0cf782b", + "https://adcontextprotocol.org/schemas/latest/enums/media-buy-status.json": "70bd2fca8832137c3b504c4b80934fdf8a57bcb45c4e1bf821fc49096aae53f9", + "https://adcontextprotocol.org/schemas/latest/enums/metric-type.json": "41eafcfaf6206670aabecd65abd5c1f2d0c4af019a3e4055d26aecfdccfd0a75", + "https://adcontextprotocol.org/schemas/latest/enums/metro-system.json": "f8cde6b0bd45c4fbabef8ff90e01c57ffc8d5a821d7f50b94de48a6ed7cf1641", + "https://adcontextprotocol.org/schemas/latest/enums/notification-type.json": "be6d4177c9350e8fdced52773b483acf464beecd567934cf020e53c43e61afac", + "https://adcontextprotocol.org/schemas/latest/enums/pacing.json": "6fb8e62bfdc40bb48e0620ed71310f21a821fdfbe644c625d01b6a68ba4e40bb", + "https://adcontextprotocol.org/schemas/latest/enums/postal-system.json": "20651c3197e7554ced864c3addb71a27ac257952988e5248db8f6f882fad12d6", + "https://adcontextprotocol.org/schemas/latest/enums/preview-output-format.json": "b14841f4e6689b3a3d2afa5740b4787ba49961d39ede2f9b92b709ad7970b32e", + "https://adcontextprotocol.org/schemas/latest/enums/pricing-model.json": "4378f72c1baec64766ff25c0352a3580df627fafe6d4f83ff2f6472cc8223c34", + "https://adcontextprotocol.org/schemas/latest/enums/promoted-offerings-requirement.json": "81ed155f3702f008a790ce102c9aeb986a30122913b919bb62f055614dac4429", + "https://adcontextprotocol.org/schemas/latest/enums/property-type.json": "7e047eb116c41b4682818f89c8b19573636a546500289d48be189945318ded83", + "https://adcontextprotocol.org/schemas/latest/enums/publisher-identifier-types.json": "3d4f8baf9ea57f525d1f126d58190588c17b05c7493ea2c9ff5737922cc96c4d", + "https://adcontextprotocol.org/schemas/latest/enums/reach-unit.json": "94b478b9ed28cd3f71b58e78191d510dfa346ff1cdecec7f67aea9a611a06d2f", + "https://adcontextprotocol.org/schemas/latest/enums/reporting-frequency.json": "b480016e39a0b8a4493e55f5bda13b153e8df7c4c07ee49586cd77bdfdab0af5", + "https://adcontextprotocol.org/schemas/latest/enums/signal-catalog-type.json": "f899ae2550950b3e2269f42c20c50bfd09c1f2870fc656e334b73758bfbf2245", + "https://adcontextprotocol.org/schemas/latest/enums/signal-source.json": "a31754104d7fac059a8a4d62fe4515dd30825703a6f795ca1a740d24d63f88b8", + "https://adcontextprotocol.org/schemas/latest/enums/signal-value-type.json": "fc2388a09442534f9931716d5ee4a4919e6b5242a2624c352b62c12a0443e32b", + "https://adcontextprotocol.org/schemas/latest/enums/sort-direction.json": "85a2cf23403297069995f14498a495c566a5a8bce4409d468d9071e18338ce6e", + "https://adcontextprotocol.org/schemas/latest/enums/task-status.json": "b45adb6b28b0b35ea5cf5564ec22d7b692e66c40d10d891d6dfe6661035c82b0", + "https://adcontextprotocol.org/schemas/latest/enums/task-type.json": "eab1baf1136e039e71cda5740810cd6f91f0b12b3897d9b211e805770820959f", + "https://adcontextprotocol.org/schemas/latest/enums/uid-type.json": "9f5a6855a5fa45aa6053e3f1aa43ca87507e966e4fadf9a37e3057070162bb81", + "https://adcontextprotocol.org/schemas/latest/enums/universal-macro.json": "dfed5f31163be00eff0b5d1d6aee09cb190058dd18b631557fb1b94de393ff7e", + "https://adcontextprotocol.org/schemas/latest/enums/update-frequency.json": "657d0460d5675ddcd7edb4cf92655b56a93cd724ab3c0b4094241ef91ca644c8", + "https://adcontextprotocol.org/schemas/latest/enums/url-asset-type.json": "8cb3c557a43a0d5f85cd9c7b83366910c570349c6ab8625583ca66454fc88c03", + "https://adcontextprotocol.org/schemas/latest/enums/validation-mode.json": "0df6bb0c18921714d48d26c2813d6fa312c5a671e1a421f9c9f9ca0c0cfa6811", + "https://adcontextprotocol.org/schemas/latest/enums/vast-tracking-event.json": "c13b3a90cfa3f13f9446185a366095576b1b92574fc468c7de432c8c141167a8", + "https://adcontextprotocol.org/schemas/latest/enums/vast-version.json": "cf0f0e11eba22c9679b96f13608540016dfa3423101b8e22238ebb56abd224dd", + "https://adcontextprotocol.org/schemas/latest/enums/wcag-level.json": "d6f9c26a09db6403d1d612d293de33a076f966b4b2b07c9b15549135dfcae0da", + "https://adcontextprotocol.org/schemas/latest/enums/webhook-response-type.json": "72ba18db0a6fabd814195e895841e4cd6af5b54c4d6a954552c36284da5c4075", + "https://adcontextprotocol.org/schemas/latest/enums/webhook-security-method.json": "80c1a7622b750af3bcfd2695569a3b348e42d5c8614378c27a65f8c7374e9165", + "https://adcontextprotocol.org/schemas/latest/extensions/extension-meta.json": "96653ac32a37fcab33ba562c62f09af7362c81cca7f95fa181499dd9d3b8eabe", + "https://adcontextprotocol.org/schemas/latest/extensions/index.json": "bfdd8760afe5adac3abcd14b36fea1e7b2187f2dd42accfe804a33e133ae019c", + "https://adcontextprotocol.org/schemas/latest/media-buy/build-creative-request.json": "ba728b5ca770c46fb5cb62b623749a4dca5d368a6096fb3818414debae12d649", + "https://adcontextprotocol.org/schemas/latest/media-buy/build-creative-response.json": "67c3e0d4b3f0c641e7e86833ab5e54c872d9cc79e673bf414abb412c81853973", + "https://adcontextprotocol.org/schemas/latest/media-buy/create-media-buy-async-response-input-required.json": "397bb7a973f943bdb2c53b36822c93ecdc815d3e5184a1129cad8648d88f378a", + "https://adcontextprotocol.org/schemas/latest/media-buy/create-media-buy-async-response-submitted.json": "7c9502344a561c3aca8752e6d95918444eb905b82413af0c6a8e4782963ce4f2", + "https://adcontextprotocol.org/schemas/latest/media-buy/create-media-buy-async-response-working.json": "f8023b1dd59955843ecf2ee3c79a81ca83411ced35daa58a6e7210ad88678e00", + "https://adcontextprotocol.org/schemas/latest/media-buy/create-media-buy-request.json": "3ecc3bd3d6f84bb7e84c49d6d54b6e1f971473356228b14b6a540820bdccd0a9", + "https://adcontextprotocol.org/schemas/latest/media-buy/create-media-buy-response.json": "91582496a11fcc050a40cab14f41a6d2c3ddd093c42c17b39d5e8f7a73868fe5", + "https://adcontextprotocol.org/schemas/latest/media-buy/get-media-buy-delivery-request.json": "8ddee92dcb78c2b250ebc9e89bbf21bf9128a6e3884d0fee2fbf38256e33ca12", + "https://adcontextprotocol.org/schemas/latest/media-buy/get-media-buy-delivery-response.json": "129865ea83513581d20b55851a2047703dfc97bd20e4778ce4e49de1e9ad7699", + "https://adcontextprotocol.org/schemas/latest/media-buy/get-products-async-response-input-required.json": "107e27baf08f80a97a0de83a24faaf37cae5c0c3112ba707ff191af1c2ad4ea6", + "https://adcontextprotocol.org/schemas/latest/media-buy/get-products-async-response-submitted.json": "f0cbf91c1e1ccc5e2c84739b8ebfbbf73cb4f64d0067847bc3eb19ec1992aa72", + "https://adcontextprotocol.org/schemas/latest/media-buy/get-products-async-response-working.json": "62be745552eeaa0aa72fc8a06b0dc89d138264ed5150158f1061cd5043c99dfa", + "https://adcontextprotocol.org/schemas/latest/media-buy/get-products-request.json": "5f1082fe85373a11d620b9aabf43c8975b19c7047df778cec5668cfefff3d0e7", + "https://adcontextprotocol.org/schemas/latest/media-buy/get-products-response.json": "d5807a9c5d36845dd1b648928c84d6f0f05b030105a5aec66965375c1c441b81", + "https://adcontextprotocol.org/schemas/latest/media-buy/list-creative-formats-request.json": "1eb753dee524bdcf9a1b5f3d35a4e6cd812aa46f974447bd1a1f632e4085df13", + "https://adcontextprotocol.org/schemas/latest/media-buy/list-creative-formats-response.json": "89fc0827dae3fa3fca6b39b38519202fc5a4374c941aacbbd5241a2a79764b52", + "https://adcontextprotocol.org/schemas/latest/media-buy/list-creatives-request.json": "2fd4a07bd836cf44cf40bdddafb2f1b07881e616f6eca9c2d45381071eedf9b8", + "https://adcontextprotocol.org/schemas/latest/media-buy/list-creatives-response.json": "33ca356b62f00318da78afb181eccd402f4cb933add7119a5b6804b5865904d2", + "https://adcontextprotocol.org/schemas/latest/media-buy/log-event-request.json": "79f382bc795e81123e01aa570e8c7fb31547f77789edb64edd5f6acc4a2c2756", + "https://adcontextprotocol.org/schemas/latest/media-buy/log-event-response.json": "97b3dc510e8d6a3edea40cbb5734d084271d9172e9b32f64c7e9dd371a7c9a65", + "https://adcontextprotocol.org/schemas/latest/media-buy/package-request.json": "e4a001ea54a60e1c9e380884a951d5a0a489b5b3d3513ebb3709be18d8e9a3a3", + "https://adcontextprotocol.org/schemas/latest/media-buy/package-update.json": "15eb51dc0dd4e72cfb192e95d2bef44129be331daf73c3f8bad7ea662edf75ff", + "https://adcontextprotocol.org/schemas/latest/media-buy/provide-performance-feedback-request.json": "8fff8a6e58cf2f8dd95e2e1cb53ef1b3c2154991a577547a2f8c75028867a81b", + "https://adcontextprotocol.org/schemas/latest/media-buy/provide-performance-feedback-response.json": "bebd13943d48ad8e8b419bd69f9fa2a9b4df30c379ae74219904e698231e7371", + "https://adcontextprotocol.org/schemas/latest/media-buy/sync-creatives-async-response-input-required.json": "62b4e86135542f4076b7bcf6edf157a7bb919e168ea97d0afb1ef1fe4ff2b8dd", + "https://adcontextprotocol.org/schemas/latest/media-buy/sync-creatives-async-response-submitted.json": "0a6df44b4224a4b38d25673d0f813022e124c7ac0bcc7eccb95e673849af7368", + "https://adcontextprotocol.org/schemas/latest/media-buy/sync-creatives-async-response-working.json": "5a336a8217d13fa112ac3dd1ed2d2c707f8abd9bb9ff05af674c22138dc24c90", + "https://adcontextprotocol.org/schemas/latest/media-buy/sync-creatives-request.json": "b65a90fb44727b08a3d9f4641f40b3299e36377b65b477976120fa449480bccf", + "https://adcontextprotocol.org/schemas/latest/media-buy/sync-creatives-response.json": "01e6785d310655ee274bb25fbb819786258e2ce3f99666d72fd8d9899fa8ffa2", + "https://adcontextprotocol.org/schemas/latest/media-buy/sync-event-sources-request.json": "9a89c03911906e3e6f05510cd1f64a548778bb9fec72fb220ca1c41580d748ff", + "https://adcontextprotocol.org/schemas/latest/media-buy/sync-event-sources-response.json": "c0e4d288b23b80f78013e2bd9af553fba7db41d9e6993b55f54b061855a0bcfe", + "https://adcontextprotocol.org/schemas/latest/media-buy/update-media-buy-async-response-input-required.json": "73ecee00cf0babc200778621b78148a54327df3436dedf349d83c734a99fc4e4", + "https://adcontextprotocol.org/schemas/latest/media-buy/update-media-buy-async-response-submitted.json": "d4736323140cf6db5522e1de5aeb1023f8a7b608d319ede26b86d28c57bea0ef", + "https://adcontextprotocol.org/schemas/latest/media-buy/update-media-buy-async-response-working.json": "ccca3256ac3179a2125922718efde61367b9046bdfdee156bdaa72c1398f2ed3", + "https://adcontextprotocol.org/schemas/latest/media-buy/update-media-buy-request.json": "818adb8936b04ba9917e80c7e6c23c2e8e00ce417dcdf57636247bce7feb8316", + "https://adcontextprotocol.org/schemas/latest/media-buy/update-media-buy-response.json": "aca3e048a43704e0f7dee2370c4ad4c4b662805e4fe39b3dde7cfea3bba1101c", + "https://adcontextprotocol.org/schemas/latest/pricing-options/cpa-option.json": "2edbea9af419fe4db7d959ac65ef067c0c7dadcb0f32bdcb12ebafa4a041f73f", + "https://adcontextprotocol.org/schemas/latest/pricing-options/cpc-option.json": "13e924180e787edab26249f7016266b6a1ae71496e0da87585e002deaddf2b33", + "https://adcontextprotocol.org/schemas/latest/pricing-options/cpcv-option.json": "7fce666773cd797ca6ab75ebb57ee9ab22936ec84c51ba58d24b81eff55b69e7", + "https://adcontextprotocol.org/schemas/latest/pricing-options/cpm-option.json": "ca572cd34796f5d060c53e51fca5119e636955ca1a50571f5cf7bd34d68c64ad", + "https://adcontextprotocol.org/schemas/latest/pricing-options/cpp-option.json": "95249f8d4119ea7cfe3d4639807809ebcc211e9793783101d47e8f5e6e956f5e", + "https://adcontextprotocol.org/schemas/latest/pricing-options/cpv-option.json": "7a2978d74c44ae584524f914ada3e3d9c0059b92d96fac2d72308ec78461020a", + "https://adcontextprotocol.org/schemas/latest/pricing-options/flat-rate-option.json": "7dff0370a4085006bd4e3ccd5ec743bad647607033712d74d72728d673d40c15", + "https://adcontextprotocol.org/schemas/latest/pricing-options/price-guidance.json": "02931d2124fe50a976534e4d51c5f4f248bdc2aae6843abcd37816474a2355c3", + "https://adcontextprotocol.org/schemas/latest/pricing-options/time-option.json": "3a8ba2bd4915ee47b352214a43c738ae90ef5396870a9d27f29dc1fc39407ff5", + "https://adcontextprotocol.org/schemas/latest/pricing-options/vcpm-option.json": "0a1e3110e2d921caf8feb4e0461c4177ab51a9f2b9aff3dd424c1d209a4ca80b", + "https://adcontextprotocol.org/schemas/latest/property/base-property-source.json": "4953f7bae585927f806926fbbac096b1a9f1e08df97ae81071233f6eb96462a0", + "https://adcontextprotocol.org/schemas/latest/property/create-property-list-request.json": "a3c96268b9ee47ab2552700c477d8f3372557369516e42cca5ee88554a284aac", + "https://adcontextprotocol.org/schemas/latest/property/create-property-list-response.json": "b7ceada500f573191cd0ef9e07817cb35f5e1b2dc1180cb15a231db460ee1655", + "https://adcontextprotocol.org/schemas/latest/property/delete-property-list-request.json": "5713450eb83436a1cf90a5636f6b54a1b0c5ffd1a15c481bca462000c4d05dd3", + "https://adcontextprotocol.org/schemas/latest/property/delete-property-list-response.json": "222fff1b07bd9d20ce0a4db6a723ed7d86b9b34ea9e5139394c444275586c4e5", + "https://adcontextprotocol.org/schemas/latest/property/feature-requirement.json": "32fe9a144d32ae888bf1169bbfcb700eebf60780ec0effac9c78ad57cd7e199f", + "https://adcontextprotocol.org/schemas/latest/property/get-property-list-request.json": "6a9ef6429a641424b019367a413f79f43db5902fc33c3e6709d7dedbafd601f8", + "https://adcontextprotocol.org/schemas/latest/property/get-property-list-response.json": "2b3a7ac1c7110fa0a8345bc1f13a1264df2bed182c0dc6e88bee5ba3d5113931", + "https://adcontextprotocol.org/schemas/latest/property/list-property-lists-request.json": "8d73ce309b8dea78b855cce61c201a8fa946c427dc2d522d1a87c4e78ca44ac5", + "https://adcontextprotocol.org/schemas/latest/property/list-property-lists-response.json": "6994a86ef681f646717f3e9f27ce6b0e33910df246bbc71b543ac68867f76ef0", + "https://adcontextprotocol.org/schemas/latest/property/property-error.json": "7077c4776c1e46d6b1284750843c502193009fb7cc912a967710419fc30fa200", + "https://adcontextprotocol.org/schemas/latest/property/property-feature-definition.json": "2030cb01aca722d5051b45399e4297f9e3307e71bb5e9743cd6fdaabcc0726d1", + "https://adcontextprotocol.org/schemas/latest/property/property-feature.json": "f6bb5d571b0c9cca78f4f97e867651a8798103ba3eb460cc87c7f9144929541a", + "https://adcontextprotocol.org/schemas/latest/property/property-list-changed-webhook.json": "4bb10e21aee5c58dc64fa0bba9e79798d3aa958e1eb02a6f028ea1799f5c03bb", + "https://adcontextprotocol.org/schemas/latest/property/property-list-filters.json": "7e9f071111eb20ebbb60a0c68dbb1cb3543bf29ad5608fdab6642532f05a1537", + "https://adcontextprotocol.org/schemas/latest/property/property-list.json": "d6830f2541a929e72587b11a5e63c437fa806fadaa9033d93b14491ea9198526", + "https://adcontextprotocol.org/schemas/latest/property/update-property-list-request.json": "6ca7e3ddfebc4ce89ab2a590d3858b97e1d6da4a57bbdddf498fd30d85d6ec56", + "https://adcontextprotocol.org/schemas/latest/property/update-property-list-response.json": "3d5e6ceca2d6273c77bab370725e41b95077deb2f55f37ca62ce440c8353b1ca", + "https://adcontextprotocol.org/schemas/latest/protocol/get-adcp-capabilities-request.json": "a93fa59dac256984ea636dbfb01f99d2387ff479bf379b968372787bb0f832c7", + "https://adcontextprotocol.org/schemas/latest/protocol/get-adcp-capabilities-response.json": "2669f3d883d7c60860ff6daf1db4ec3f2a4facb8af23c4350deab0a6a62dee95", + "https://adcontextprotocol.org/schemas/latest/signals/activate-signal-request.json": "5791ed345768830e7e0eaf72d03027384550ccbd79b9acc5ef45c5f34bf705f2", + "https://adcontextprotocol.org/schemas/latest/signals/activate-signal-response.json": "9da0bccfb7c1534f9a279f6689b6771a38b15e2064a01ec1b310a44bb14aa733", + "https://adcontextprotocol.org/schemas/latest/signals/get-signals-request.json": "9cc79ae0db10f5e4d02f19123e3312f3e57bd6eee4b534f72065ce933e6bfb9e", + "https://adcontextprotocol.org/schemas/latest/signals/get-signals-response.json": "7329b40b98e515dc4a5e2dd422a20258a16687c67fbf7953bca8ee45d689ddc1", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-capabilities.json": "a583b04f6acd5c8418c6b9613842e12d6b00a1f36241990d02b17c71ebf74356", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-get-offering-request.json": "953346b451471a4c930649fb5dc470361763009b1a2efa0f4666a0b7acfb16c9", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-get-offering-response.json": "e0cc6da05594aa7080319bbc506cf56d3f7c541504cde86e27573917078410e8", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-identity.json": "6b1fad0cb8433b15055b7e2a8271d7ee1ac405db6f5e19bb9aa8eb405a747797", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-initiate-session-request.json": "dd872808799aa225cb7c5723d162aaa21c3265b84f26ebb13dd12b4b6076b26c", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-initiate-session-response.json": "3eb8440b2be7b8d4777003b34f3094fd6d1c6b87a3236163d584192352b0c7f7", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-send-message-request.json": "b8a789094d4288cf277070e762f01bb22b3248c9730797603974891741bbc3a4", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-send-message-response.json": "1541e484b3138381c1af121dae7dea5692441fd9d5a55384e57fe7661c6c1c22", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-terminate-session-request.json": "8121c3cbf497bef6e5b265a3520daa8cb1c38cd133e8d593b4558f175f7fab95", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-terminate-session-response.json": "446b2ff92b8522d805af1592334d56c045e891608bc87f751007c8afe552d188", + "https://adcontextprotocol.org/schemas/latest/sponsored-intelligence/si-ui-element.json": "e7d434246c38e1d047896cfdfec30ffda5f842ea8a4f699c5701c6c7c22bfaf8" } \ No newline at end of file diff --git a/schemas/cache/adagents.json b/schemas/cache/adagents.json index 9353e5bd..045dd46b 100644 --- a/schemas/cache/adagents.json +++ b/schemas/cache/adagents.json @@ -3,12 +3,12 @@ "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-beta.3/adagents.json", + "$schema": "/schemas/latest/adagents.json", "authoritative_location": "https://cdn.example.com/adagents/v2/adagents.json", "last_updated": "2025-01-15T10:00:00Z" }, { - "$schema": "/schemas/3.0.0-beta.3/adagents.json", + "$schema": "/schemas/latest/adagents.json", "authorized_agents": [ { "authorization_type": "property_tags", @@ -41,7 +41,7 @@ } }, { - "$schema": "/schemas/3.0.0-beta.3/adagents.json", + "$schema": "/schemas/latest/adagents.json", "authorized_agents": [ { "authorization_type": "property_tags", @@ -150,7 +150,7 @@ } }, { - "$schema": "/schemas/3.0.0-beta.3/adagents.json", + "$schema": "/schemas/latest/adagents.json", "authorized_agents": [ { "authorization_type": "property_tags", @@ -189,7 +189,7 @@ } }, { - "$schema": "/schemas/3.0.0-beta.3/adagents.json", + "$schema": "/schemas/latest/adagents.json", "authorized_agents": [ { "authorization_type": "publisher_properties", @@ -235,7 +235,7 @@ "last_updated": "2025-01-10T17:00:00Z" }, { - "$schema": "/schemas/3.0.0-beta.3/adagents.json", + "$schema": "/schemas/latest/adagents.json", "authorized_agents": [ { "authorization_type": "property_tags", @@ -310,7 +310,7 @@ } }, { - "$schema": "/schemas/3.0.0-beta.3/adagents.json", + "$schema": "/schemas/latest/adagents.json", "authorized_agents": [ { "authorization_type": "signal_tags", diff --git a/schemas/cache/brand.json b/schemas/cache/brand.json index 8c9d567b..ff50e15e 100644 --- a/schemas/cache/brand.json +++ b/schemas/cache/brand.json @@ -3,49 +3,59 @@ "definitions": { "asset": { "additionalProperties": true, - "description": "Brand asset (image, video, audio)", + "description": "Brand asset (image, video, audio, text)", "properties": { "asset_id": { "description": "Unique identifier", "type": "string" }, "asset_type": { - "description": "Asset type", - "enum": [ - "image", - "video", - "audio", - "text" - ], + "$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" + }, "format": { - "description": "File format (jpg, mp4, etc.)", + "description": "File format (e.g., 'jpg', 'mp4', 'mp3')", "type": "string" }, "height": { + "description": "Image/video height in pixels", "type": "integer" }, + "metadata": { + "additionalProperties": true, + "description": "Additional asset-specific metadata", + "type": "object" + }, "name": { "description": "Human-readable name", "type": "string" }, "tags": { - "description": "Tags for discovery (e.g., 'hero', 'lifestyle', 'product')", + "description": "Tags for discovery (e.g., 'hero', 'lifestyle', 'product', 'holiday')", "items": { "type": "string" }, "type": "array" }, "url": { - "description": "URL to asset", + "description": "URL to CDN-hosted asset file", "format": "uri", "type": "string" }, "width": { + "description": "Image/video width in pixels", "type": "integer" } }, @@ -90,7 +100,7 @@ }, "brand": { "additionalProperties": true, - "description": "A brand within a house portfolio. Combines identity (who) with creative assets (how to represent). Referenced as house + brand_id.", + "description": "A brand within a house portfolio. Combines identity (who) with creative assets (how to represent). Referenced as domain + brand_id.", "properties": { "assets": { "description": "Brand asset library", @@ -118,11 +128,26 @@ }, "brand_agent": { "$ref": "#/definitions/brand_agent", - "description": "Brand agent that provides dynamic brand manifest data. Agent implements get_brand_manifest({ house, brand_id })." + "description": "Brand agent that provides dynamic brand data via MCP" }, "colors": { "$ref": "#/definitions/colors" }, + "contact": { + "description": "Brand-level contact information", + "properties": { + "email": { + "description": "Contact email", + "format": "email", + "type": "string" + }, + "phone": { + "description": "Contact phone number", + "type": "string" + } + }, + "type": "object" + }, "description": { "description": "Brand description", "type": "string" @@ -245,6 +270,11 @@ } ] }, + "url": { + "description": "Primary brand URL for context and asset discovery", + "format": "uri", + "type": "string" + }, "voice": { "additionalProperties": true, "description": "TTS voice configuration", @@ -271,7 +301,7 @@ }, "brand_agent": { "additionalProperties": true, - "description": "Reference to a brand agent that provides brand manifest data via MCP", + "description": "Reference to a brand agent that provides brand data via MCP", "properties": { "id": { "description": "Agent identifier (useful for logging, multi-tenant DAMs)", @@ -443,14 +473,33 @@ }, "logo": { "additionalProperties": true, - "description": "Brand logo asset", + "description": "Brand logo asset with structured fields for orientation, background compatibility, and variant type", "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" + }, "height": { "description": "Height in pixels", "type": "integer" }, + "orientation": { + "description": "Logo aspect ratio orientation. square: ~1:1, horizontal: wide, vertical: tall, stacked: vertically arranged elements", + "enum": [ + "square", + "horizontal", + "vertical", + "stacked" + ], + "type": "string" + }, "tags": { - "description": "Semantic tags (e.g., 'dark', 'light', 'square', 'horizontal', 'icon')", + "description": "Additional semantic tags for custom categorization beyond the standard orientation, background, and variant fields", "items": { "type": "string" }, @@ -461,6 +510,21 @@ "format": "uri", "type": "string" }, + "usage": { + "description": "Human-readable description of when to use this logo variant (e.g., 'Primary logo for use on light backgrounds')", + "type": "string" + }, + "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" + }, "width": { "description": "Width in pixels", "type": "integer" @@ -476,16 +540,26 @@ "description": "Product catalog for e-commerce brands", "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": [ @@ -495,12 +569,14 @@ "type": "object" }, "categories": { + "description": "Product categories available in the catalog", "items": { "type": "string" }, "type": "array" }, "feed_format": { + "description": "Format of the product feed", "enum": [ "google_merchant_center", "facebook_catalog", @@ -510,10 +586,17 @@ "type": "string" }, "feed_url": { + "description": "URL to product catalog feed", "format": "uri", "type": "string" }, + "last_updated": { + "description": "When the product catalog was last updated", + "format": "date-time", + "type": "string" + }, "update_frequency": { + "description": "How frequently the product catalog is updated", "enum": [ "realtime", "hourly", @@ -585,16 +668,16 @@ "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-beta.3/brand.json", + "$schema": "/schemas/latest/brand.json", "authoritative_location": "https://adcontextprotocol.org/brand/abc123/brand.json" }, { - "$schema": "/schemas/3.0.0-beta.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-beta.3/brand.json", + "$schema": "/schemas/latest/brand.json", "brand_agent": { "id": "acme_brand_agent", "url": "https://agent.acme.com/mcp" @@ -602,24 +685,34 @@ "version": "1.0" }, { - "$schema": "/schemas/3.0.0-beta.3/brand.json", + "$schema": "/schemas/latest/brand.json", "brands": [ { "colors": { "primary": "#FF6600", "secondary": "#0066CC" }, + "contact": { + "email": "brands@pg.com" + }, "description": "Laundry detergent brand", "id": "tide", "industry": "cpg", "keller_type": "master", "logos": [ { - "tags": [ - "square", - "primary" - ], - "url": "https://cdn.pg.com/tide/logo-square.png" + "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" } ], "names": [ @@ -661,7 +754,8 @@ "Emphasize cleaning power" ], "voice": "clean, fresh, trustworthy" - } + }, + "url": "https://tide.com" }, { "colors": { @@ -672,10 +766,9 @@ "keller_type": "master", "logos": [ { - "tags": [ - "primary" - ], - "url": "https://cdn.pg.com/pampers/logo.png" + "orientation": "horizontal", + "url": "https://cdn.pg.com/pampers/logo.png", + "variant": "primary" } ], "names": [ @@ -689,7 +782,8 @@ "primary": true, "type": "website" } - ] + ], + "url": "https://pampers.com" } ], "contact": { @@ -705,7 +799,7 @@ "version": "1.0" }, { - "$schema": "/schemas/3.0.0-beta.3/brand.json", + "$schema": "/schemas/latest/brand.json", "authorized_operators": [ { "brands": [ @@ -746,18 +840,18 @@ "keller_type": "master", "logos": [ { - "tags": [ - "dark", - "icon" - ], - "url": "https://cdn.nike.com/swoosh-dark.svg" + "background": "dark-bg", + "orientation": "horizontal", + "url": "https://cdn.nike.com/swoosh-dark.svg", + "usage": "Swoosh icon for dark backgrounds", + "variant": "icon" }, { - "tags": [ - "full", - "horizontal" - ], - "url": "https://cdn.nike.com/logo-full.svg" + "background": "light-bg", + "orientation": "horizontal", + "url": "https://cdn.nike.com/logo-full.svg", + "usage": "Full logo with wordmark for light backgrounds", + "variant": "full-lockup" } ], "names": [ @@ -789,7 +883,8 @@ } ], "tagline": "Just Do It", - "tone": "inspirational, bold, athletic" + "tone": "inspirational, bold, athletic", + "url": "https://nike.com" }, { "brand_agent": { @@ -804,10 +899,10 @@ "keller_type": "endorsed", "logos": [ { - "tags": [ - "icon" - ], - "url": "https://cdn.nike.com/jumpman.svg" + "background": "transparent-bg", + "orientation": "square", + "url": "https://cdn.nike.com/jumpman.svg", + "variant": "icon" } ], "names": [ @@ -832,17 +927,17 @@ "identifier": "jumpman23.com", "type": "website" } - ] + ], + "url": "https://jordan.com" }, { "id": "converse", "keller_type": "independent", "logos": [ { - "tags": [ - "icon" - ], - "url": "https://cdn.converse.com/star.svg" + "orientation": "square", + "url": "https://cdn.converse.com/star.svg", + "variant": "icon" } ], "names": [ @@ -856,7 +951,8 @@ "primary": true, "type": "website" } - ] + ], + "url": "https://converse.com" } ], "house": { diff --git a/schemas/cache/core/brand-manifest-ref.json b/schemas/cache/core/brand-manifest-ref.json deleted file mode 100644 index e809438b..00000000 --- a/schemas/cache/core/brand-manifest-ref.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "description": "Brand manifest provided either as an inline object or a URL string pointing to a hosted manifest", - "examples": [ - { - "data": { - "colors": { - "primary": "#FF6B35" - }, - "name": "ACME Corporation", - "url": "https://acmecorp.com" - }, - "description": "Inline brand manifest" - }, - { - "data": "https://cdn.acmecorp.com/brand-manifest.json", - "description": "URL string reference to hosted manifest" - } - ], - "oneOf": [ - { - "$ref": "brand-manifest.json", - "description": "Inline brand manifest object" - }, - { - "description": "URL to a hosted brand manifest JSON file. The manifest at this URL must conform to the brand-manifest.json schema.", - "format": "uri", - "type": "string" - } - ], - "title": "Brand Manifest Reference" -} \ No newline at end of file diff --git a/schemas/cache/core/brand-manifest.json b/schemas/cache/core/brand-manifest.json deleted file mode 100644 index 4c555e20..00000000 --- a/schemas/cache/core/brand-manifest.json +++ /dev/null @@ -1,686 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": true, - "description": "Standardized brand information manifest for creative generation and media buying. Enables low-friction creative workflows by providing brand context that can be easily cached and shared across requests.", - "examples": [ - { - "data": { - "name": "Bob's Fun Burgers", - "url": "https://bobsfunburgers.com" - }, - "description": "Example with both URL and name" - }, - { - "data": { - "colors": { - "primary": "#0071CE", - "secondary": "#FFC220" - }, - "name": "Great Value", - "tone": { - "voice": "affordable and trustworthy" - } - }, - "description": "Example: white-label brand without dedicated URL" - }, - { - "data": { - "assets": [ - { - "asset_id": "hero_winter_2024", - "asset_type": "image", - "format": "jpg", - "height": 1080, - "name": "Winter Campaign Hero", - "tags": [ - "hero", - "winter", - "holiday", - "lifestyle" - ], - "url": "https://cdn.acmecorp.com/hero-winter-2024.jpg", - "width": 1920 - }, - { - "asset_id": "product_video_30s", - "asset_type": "video", - "duration_seconds": 30, - "format": "mp4", - "height": 1080, - "name": "Product Demo 30 Second", - "tags": [ - "product", - "demo", - "30s" - ], - "url": "https://cdn.acmecorp.com/product-demo-30s.mp4", - "width": 1920 - } - ], - "colors": { - "accent": "#F7931E", - "background": "#FFFFFF", - "primary": "#FF6B35", - "secondary": "#004E89", - "text": "#1A1A1A" - }, - "disclaimers": [ - { - "context": "health_claims", - "required": true, - "text": "Results may vary. Consult a professional before use." - } - ], - "fonts": { - "primary": "Helvetica Neue", - "secondary": "Georgia" - }, - "industry": "technology", - "logos": [ - { - "background": "light-bg", - "height": 400, - "orientation": "horizontal", - "url": "https://cdn.acmecorp.com/logo-on-light.png", - "usage": "Primary logo for use on light backgrounds", - "variant": "primary", - "width": 1200 - }, - { - "background": "dark-bg", - "height": 400, - "orientation": "horizontal", - "url": "https://cdn.acmecorp.com/logo-on-dark.png", - "usage": "Primary logo for use on dark backgrounds", - "variant": "primary", - "width": 1200 - }, - { - "background": "transparent-bg", - "height": 512, - "orientation": "square", - "url": "https://cdn.acmecorp.com/icon.png", - "usage": "Icon-only variant for small formats", - "variant": "icon", - "width": 512 - } - ], - "name": "ACME Corporation", - "privacy_policy_url": "https://acmecorp.com/privacy", - "product_catalog": { - "categories": [ - "electronics/computers", - "electronics/accessories" - ], - "feed_format": "google_merchant_center", - "feed_url": "https://acmecorp.com/products.xml", - "last_updated": "2024-03-15T10:00:00Z", - "update_frequency": "hourly" - }, - "tagline": "Innovation You Can Trust", - "target_audience": "business decision-makers aged 35-55", - "tone": { - "attributes": [ - "confident", - "innovative", - "approachable", - "expert" - ], - "donts": [ - "Avoid hyperbole or exaggeration", - "Don't use overly casual language", - "Avoid technical jargon without explanation", - "Don't make unsubstantiated claims" - ], - "dos": [ - "Use clear, direct language", - "Highlight innovation and reliability", - "Back claims with specifics", - "Address decision-makers directly" - ], - "voice": "professional and trustworthy" - }, - "url": "https://acmecorp.com" - }, - "description": "Full brand manifest with all fields" - }, - { - "data": { - "name": "Shop Example", - "privacy_policy_url": "https://shopexample.com/privacy", - "product_catalog": { - "agentic_checkout": { - "endpoint": "https://api.shopexample.com/checkout_sessions", - "spec": "openai_agentic_checkout_v1", - "supported_payment_providers": [ - "stripe", - "adyen" - ] - }, - "feed_format": "openai_product_feed", - "feed_url": "https://shopexample.com/products.jsonl.gz", - "update_frequency": "daily" - }, - "url": "https://shopexample.com" - }, - "description": "E-commerce brand with OpenAI product feed and agentic checkout" - } - ], - "properties": { - "assets": { - "description": "Brand asset library with explicit assets and tags. Assets are referenced inline with URLs pointing to CDN-hosted files.", - "items": { - "additionalProperties": true, - "properties": { - "asset_id": { - "description": "Unique identifier for this asset", - "type": "string" - }, - "asset_type": { - "$ref": "../enums/asset-content-type.json", - "description": "Type of asset. Note: Brand manifests typically contain basic media assets (image, video, audio, text). Code assets (html, javascript, css) and ad markup (vast, daast) are usually not part of brand asset libraries." - }, - "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" - }, - "format": { - "description": "File format (e.g., 'jpg', 'mp4', 'mp3')", - "type": "string" - }, - "height": { - "description": "Image/video height in pixels", - "type": "integer" - }, - "metadata": { - "additionalProperties": true, - "description": "Additional asset-specific metadata", - "type": "object" - }, - "name": { - "description": "Human-readable asset name", - "type": "string" - }, - "tags": { - "description": "Tags for asset discovery (e.g., 'holiday', 'lifestyle', 'product_shot')", - "items": { - "type": "string" - }, - "type": "array" - }, - "url": { - "description": "URL to CDN-hosted asset file", - "format": "uri", - "type": "string" - }, - "width": { - "description": "Image/video width in pixels", - "type": "integer" - } - }, - "required": [ - "asset_id", - "asset_type", - "url" - ], - "type": "object" - }, - "type": "array" - }, - "avatar": { - "description": "Brand avatar configuration for visual conversational experiences", - "properties": { - "avatar_id": { - "description": "Provider-specific avatar identifier", - "type": "string" - }, - "provider": { - "description": "Avatar provider (e.g., 'd-id', 'heygen', 'synthesia')", - "type": "string" - }, - "settings": { - "additionalProperties": true, - "description": "Provider-specific avatar settings", - "type": "object" - } - }, - "type": "object" - }, - "colors": { - "description": "Brand color palette. Each role accepts a single hex color or an array of hex colors for brands with multiple values per role.", - "properties": { - "accent": { - "description": "Accent color(s)", - "oneOf": [ - { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - { - "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - "minItems": 1, - "type": "array" - } - ] - }, - "background": { - "description": "Background color(s)", - "oneOf": [ - { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - { - "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - "minItems": 1, - "type": "array" - } - ] - }, - "primary": { - "description": "Primary brand color(s)", - "oneOf": [ - { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - { - "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - "minItems": 1, - "type": "array" - } - ] - }, - "secondary": { - "description": "Secondary brand color(s)", - "oneOf": [ - { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - { - "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - "minItems": 1, - "type": "array" - } - ] - }, - "text": { - "description": "Text color(s)", - "oneOf": [ - { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - { - "items": { - "pattern": "^#[0-9A-Fa-f]{6}$", - "type": "string" - }, - "minItems": 1, - "type": "array" - } - ] - } - }, - "type": "object" - }, - "contact": { - "description": "Brand contact information", - "properties": { - "email": { - "description": "Contact email", - "format": "email", - "type": "string" - }, - "phone": { - "description": "Contact phone number", - "type": "string" - } - }, - "type": "object" - }, - "disclaimers": { - "description": "Legal disclaimers or required text that must appear in creatives", - "items": { - "properties": { - "context": { - "description": "When this disclaimer applies (e.g., 'financial_products', 'health_claims', 'all')", - "type": "string" - }, - "required": { - "default": true, - "description": "Whether this disclaimer must appear", - "type": "boolean" - }, - "text": { - "description": "Disclaimer text", - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - }, - "type": "array" - }, - "fonts": { - "description": "Brand typography guidelines", - "properties": { - "font_urls": { - "description": "URLs to web font files if using custom fonts", - "items": { - "format": "uri", - "type": "string" - }, - "type": "array" - }, - "primary": { - "description": "Primary font family name", - "type": "string" - }, - "secondary": { - "description": "Secondary font family name", - "type": "string" - } - }, - "type": "object" - }, - "industry": { - "description": "Industry or vertical (e.g., 'retail', 'automotive', 'finance', 'healthcare')", - "type": "string" - }, - "logos": { - "description": "Brand logo assets with structured fields for orientation, background compatibility, and variant type. Use the orientation, background, and variant enum fields for reliable filtering by creative agents.", - "items": { - "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" - }, - "height": { - "description": "Logo height in pixels", - "type": "integer" - }, - "orientation": { - "description": "Logo aspect ratio orientation. square: ~1:1, horizontal: wide, vertical: tall, stacked: vertically arranged elements", - "enum": [ - "square", - "horizontal", - "vertical", - "stacked" - ], - "type": "string" - }, - "tags": { - "description": "Additional semantic tags for custom categorization beyond the standard orientation, background, and variant fields.", - "items": { - "type": "string" - }, - "type": "array" - }, - "url": { - "description": "URL to the logo asset", - "format": "uri", - "type": "string" - }, - "usage": { - "description": "Human-readable description of when to use this logo variant (e.g., 'Primary logo for use on light backgrounds', 'Icon-only variant for small formats')", - "type": "string" - }, - "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" - }, - "width": { - "description": "Logo width in pixels", - "type": "integer" - } - }, - "required": [ - "url" - ], - "type": "object" - }, - "type": "array" - }, - "metadata": { - "description": "Additional brand metadata", - "properties": { - "created_date": { - "description": "When this brand manifest was created", - "format": "date-time", - "type": "string" - }, - "updated_date": { - "description": "When this brand manifest was last updated", - "format": "date-time", - "type": "string" - }, - "version": { - "description": "Brand card version number", - "type": "string" - } - }, - "type": "object" - }, - "name": { - "description": "Brand or business name", - "type": "string" - }, - "privacy_policy_url": { - "description": "URL to the brand's privacy policy. Used for consumer consent flows when personal data may be shared with the advertiser. AI platforms can use this to present explicit privacy choices to users before data handoff.", - "format": "uri", - "type": "string" - }, - "product_catalog": { - "additionalProperties": true, - "description": "Product catalog information for e-commerce advertisers. Enables SKU-level creative generation and product selection.", - "properties": { - "agentic_checkout": { - "description": "Agentic checkout endpoint configuration. Enables AI agents to complete purchases on behalf of users through a structured checkout API.", - "properties": { - "endpoint": { - "description": "Base URL for checkout session API (e.g., https://merchant.com/api/checkout_sessions)", - "format": "uri", - "type": "string" - }, - "spec": { - "description": "Checkout API specification implemented by the endpoint", - "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 (for filtering)", - "items": { - "type": "string" - }, - "type": "array" - }, - "feed_format": { - "default": "google_merchant_center", - "description": "Format of the product feed. Use 'openai_product_feed' for feeds conforming to the OpenAI Commerce Product Feed specification.", - "enum": [ - "google_merchant_center", - "facebook_catalog", - "openai_product_feed", - "custom" - ], - "type": "string" - }, - "feed_url": { - "description": "URL to product catalog feed", - "format": "uri", - "type": "string" - }, - "last_updated": { - "description": "When the product catalog was last updated", - "format": "date-time", - "type": "string" - }, - "update_frequency": { - "description": "How frequently the product catalog is updated", - "enum": [ - "realtime", - "hourly", - "daily", - "weekly" - ], - "type": "string" - } - }, - "required": [ - "feed_url" - ], - "type": "object" - }, - "tagline": { - "description": "Brand tagline or slogan", - "type": "string" - }, - "target_audience": { - "description": "Primary target audience description", - "type": "string" - }, - "tone": { - "description": "Brand voice and messaging tone guidelines for creative agents.", - "oneOf": [ - { - "description": "Simple tone descriptors for backwards compatibility", - "type": "string" - }, - { - "description": "Structured brand voice guidelines", - "properties": { - "attributes": { - "description": "Personality traits that characterize the brand voice", - "examples": [ - [ - "friendly", - "optimistic", - "conversational", - "authentic" - ] - ], - "items": { - "type": "string" - }, - "type": "array" - }, - "donts": { - "description": "Guardrails to avoid brand violations - what NOT to do", - "examples": [ - [ - "Avoid corporate jargon", - "Don't be overly formal", - "Don't make exaggerated claims" - ] - ], - "items": { - "type": "string" - }, - "type": "array" - }, - "dos": { - "description": "Specific guidance for copy generation - what TO do", - "examples": [ - [ - "Use simple, everyday language", - "Address the reader directly", - "Keep sentences short and punchy" - ] - ], - "items": { - "type": "string" - }, - "type": "array" - }, - "voice": { - "description": "High-level voice descriptor (e.g., 'warm and inviting', 'professional and trustworthy')", - "type": "string" - } - }, - "type": "object" - } - ] - }, - "url": { - "description": "Primary brand URL for context and asset discovery. Creative agents can infer brand information from this URL.", - "format": "uri", - "type": "string" - }, - "voice": { - "description": "Brand voice configuration for audio/conversational experiences", - "properties": { - "provider": { - "description": "TTS provider (e.g., 'elevenlabs', 'openai', 'amazon_polly')", - "type": "string" - }, - "settings": { - "additionalProperties": true, - "description": "Provider-specific voice settings (speed, pitch, etc.)", - "type": "object" - }, - "voice_id": { - "description": "Provider-specific voice identifier", - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "name" - ], - "title": "Brand Manifest", - "type": "object" -} \ No newline at end of file diff --git a/schemas/cache/core/brand-ref.json b/schemas/cache/core/brand-ref.json index cade3338..2161b35a 100644 --- a/schemas/cache/core/brand-ref.json +++ b/schemas/cache/core/brand-ref.json @@ -1,35 +1,33 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": false, - "description": "Reference to a brand within a house portfolio. Similar to property references (publisher + property_id), brands are identified by house domain + brand_id.", + "description": "Reference to a brand by domain and optional brand_id. The domain hosts /.well-known/brand.json or is registered in the brand registry. For single-brand domains, brand_id can be omitted. For house-of-brands domains, brand_id identifies the specific brand.", "examples": [ { "brand_id": "tide", - "house": "pg.com" + "domain": "pg.com" }, { "brand_id": "air_jordan", - "house": "nikeinc.com" + "domain": "nikeinc.com" }, { - "brand_id": "cheerios", - "house": "generalmills.com" + "domain": "bobsburgers.com" } ], "properties": { "brand_id": { "$ref": "brand-id.json", - "description": "Brand identifier within the house portfolio" + "description": "Brand identifier within the house portfolio. Optional for single-brand domains." }, - "house": { - "description": "Domain where the house's brand.json is hosted (e.g., 'pg.com', 'nikeinc.com')", + "domain": { + "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])?)*$", "type": "string" } }, "required": [ - "house", - "brand_id" + "domain" ], "title": "Brand Reference", "type": "object" diff --git a/schemas/cache/core/creative-brief-ref.json b/schemas/cache/core/creative-brief-ref.json new file mode 100644 index 00000000..547679d0 --- /dev/null +++ b/schemas/cache/core/creative-brief-ref.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Creative brief provided either as an inline object or a URL string pointing to a hosted brief", + "examples": [ + { + "data": { + "audience": "Gift shoppers aged 25-55", + "messaging": { + "cta": "Shop Holiday Deals", + "headline": "Give the Gift of Style" + }, + "name": "Holiday Campaign 2025", + "objective": "conversion" + }, + "description": "Inline creative brief" + }, + { + "data": "https://cdn.example.com/briefs/holiday-2025.json", + "description": "URL string reference to hosted brief" + } + ], + "oneOf": [ + { + "$ref": "creative-brief.json", + "description": "Inline creative brief object" + }, + { + "description": "URL to a hosted creative brief JSON file. The brief at this URL must conform to the creative-brief.json schema.", + "format": "uri", + "type": "string" + } + ], + "title": "Creative Brief Reference" +} \ No newline at end of file diff --git a/schemas/cache/core/creative-brief.json b/schemas/cache/core/creative-brief.json new file mode 100644 index 00000000..c7cb34b4 --- /dev/null +++ b/schemas/cache/core/creative-brief.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "description": "Campaign-level creative context for AI-powered creative generation. Provides the layer between brand identity (stable across campaigns) and individual creative execution (per-request). A brand has one identity (defined in brand.json) but different creative briefs for each campaign or flight.", + "properties": { + "audience": { + "description": "Target audience description for this campaign", + "type": "string" + }, + "messaging": { + "additionalProperties": true, + "description": "Messaging framework for the campaign", + "properties": { + "cta": { + "description": "Call-to-action text", + "type": "string" + }, + "headline": { + "description": "Primary headline", + "type": "string" + }, + "key_messages": { + "description": "Key messages to communicate in priority order", + "items": { + "type": "string" + }, + "type": "array" + }, + "tagline": { + "description": "Supporting tagline or sub-headline", + "type": "string" + } + }, + "type": "object" + }, + "name": { + "description": "Campaign or flight name for identification", + "type": "string" + }, + "objective": { + "description": "Campaign objective that guides creative tone and call-to-action strategy", + "enum": [ + "awareness", + "consideration", + "conversion", + "retention", + "engagement" + ], + "type": "string" + }, + "reference_assets": { + "description": "Visual and strategic reference materials such as mood boards, product shots, example creatives, and strategy documents", + "items": { + "$ref": "reference-asset.json" + }, + "type": "array" + }, + "territory": { + "description": "Creative territory or positioning the campaign should occupy", + "type": "string" + }, + "tone": { + "description": "Desired tone for this campaign, modulating the brand's base tone (e.g., 'playful and festive', 'premium and aspirational')", + "type": "string" + } + }, + "required": [ + "name" + ], + "title": "Creative Brief", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/core/creative-variant.json b/schemas/cache/core/creative-variant.json index 13e66a09..3bdc5448 100644 --- a/schemas/cache/core/creative-variant.json +++ b/schemas/cache/core/creative-variant.json @@ -41,7 +41,7 @@ }, "manifest": { "$ref": "creative-manifest.json", - "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 manifest. Pass to preview_creative to re-render." + "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." }, "variant_id": { "description": "Platform-assigned identifier for this variant", diff --git a/schemas/cache/core/format.json b/schemas/cache/core/format.json index fd48c898..00005914 100644 --- a/schemas/cache/core/format.json +++ b/schemas/cache/core/format.json @@ -661,7 +661,7 @@ "type": "string" }, "output_format_ids": { - "description": "For generative formats: array of format IDs that this format can generate. When a format accepts inputs like brand_manifest and message, this specifies what concrete output formats can be produced (e.g., a generative banner format might output standard image banner formats).", + "description": "For generative formats: array of format IDs that this format can generate. When a format accepts inputs like brand context and message, this specifies what concrete output formats can be produced (e.g., a generative banner format might output standard image banner formats).", "items": { "$ref": "format-id.json" }, diff --git a/schemas/cache/core/product.json b/schemas/cache/core/product.json index c76c38cb..55e5c0d2 100644 --- a/schemas/cache/core/product.json +++ b/schemas/cache/core/product.json @@ -8,7 +8,7 @@ "type": "string" }, "catalog_match": { - "description": "When the buyer provides a brand_manifest with product_catalog, indicates which of the buyer's catalog items are eligible for this product. Enables buyers to make informed product_selector choices in create_media_buy. Only present for products where catalog matching is relevant (e.g. sponsored product listings on retail media). Sellers SHOULD include at least one of matched_gtins or matched_skus.", + "description": "When the buyer provides a brand with product_catalog, indicates which of the buyer's catalog items are eligible for this product. Enables buyers to make informed product_selector choices in create_media_buy. Only present for products where catalog matching is relevant (e.g. sponsored product listings on retail media). Sellers SHOULD include at least one of matched_gtins or matched_skus.", "properties": { "matched_gtins": { "description": "GTINs from the buyer's catalog that are eligible on this product's inventory. Buyers can use these values in product_selectors.manifest_gtins when creating media buys. Standard GTIN formats (GTIN-8 through GTIN-14).", @@ -110,11 +110,6 @@ "description": "Detailed description of the product and its inventory", "type": "string" }, - "estimated_exposures": { - "description": "Estimated exposures/impressions for guaranteed products", - "minimum": 0, - "type": "integer" - }, "expires_at": { "description": "Expiration timestamp for custom products", "format": "date-time", @@ -123,6 +118,10 @@ "ext": { "$ref": "ext.json" }, + "forecast": { + "$ref": "delivery-forecast.json", + "description": "Forecasted delivery metrics for this product. Gives buyers an estimate of expected performance before requesting a proposal." + }, "format_ids": { "description": "Array of supported creative format IDs - structured format_id objects with agent_url and id", "items": { diff --git a/schemas/cache/core/promoted-offerings.json b/schemas/cache/core/promoted-offerings.json index 7513c36d..eb3271fd 100644 --- a/schemas/cache/core/promoted-offerings.json +++ b/schemas/cache/core/promoted-offerings.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": true, - "description": "Complete offering specification combining brand manifest, product selectors, and optional SI agent endpoint. Provides all context needed for creative generation and/or conversational experiences about what is being promoted. When si_agent_url is present, hosts can connect users to conversational experiences about any of the offerings.", + "description": "Complete offering specification combining brand reference, product selectors, and optional SI agent endpoint. Provides all context needed for creative generation and/or conversational experiences about what is being promoted. When si_agent_url is present, hosts can connect users to conversational experiences about any of the offerings.", "examples": [ { "data": { @@ -14,9 +14,8 @@ "holiday" ] }, - "brand_manifest": { - "name": "Brand Name", - "url": "https://brand.com" + "brand": { + "domain": "acmecorp.com" }, "product_selectors": { "manifest_skus": [ @@ -29,10 +28,12 @@ }, { "data": { - "brand_manifest": "https://brand.com/manifest.json", + "brand": { + "domain": "acmecorp.com" + }, "offerings": [ { - "checkout_url": "https://brand.com/signup", + "checkout_url": "https://acmecorp.com/signup", "description": "Try our platform free for 30 days", "name": "Free 30-day trial", "offering_id": "q1-2025-trial", @@ -41,28 +42,31 @@ }, { "description": "Our flagship enterprise solution", - "landing_url": "https://brand.com/enterprise", + "landing_url": "https://acmecorp.com/enterprise", "name": "Enterprise Platform", "offering_id": "standard-product" } ], - "si_agent_url": "https://agent.brand.com/mcp" + "si_agent_url": "https://agent.acmecorp.com/mcp" }, "description": "Offerings with SI agent for conversational experiences" }, { "data": { - "brand_manifest": "https://brand.com/manifest.json", + "brand": { + "brand_id": "tide", + "domain": "pg.com" + }, "offerings": [ { "description": "Up to 50% off summer collection", - "landing_url": "https://brand.com/summer", + "landing_url": "https://tide.com/summer", "name": "Summer Sale", "offering_id": "summer-campaign", - "portfolio_ref": "https://brand.com/portfolios/summer-2025.json" + "portfolio_ref": "https://tide.com/portfolios/summer-2025.json" } ], - "si_agent_url": "https://agent.brand.com/mcp" + "si_agent_url": "https://agent.tide.com/mcp" }, "description": "Offerings with both creatives and SI" } @@ -70,7 +74,7 @@ "properties": { "asset_selectors": { "additionalProperties": true, - "description": "Selectors to choose specific assets from the brand manifest", + "description": "Selectors to choose specific assets from the brand's asset library", "properties": { "asset_types": { "description": "Filter by asset type (e.g., ['image', 'video'])", @@ -109,9 +113,9 @@ }, "type": "object" }, - "brand_manifest": { - "$ref": "brand-manifest-ref.json", - "description": "Brand information manifest containing assets, themes, and guidelines. Can be provided inline or as a URL reference to a hosted manifest." + "brand": { + "$ref": "brand-ref.json", + "description": "Brand reference. Resolved to full brand identity (logos, colors, tone, assets) at execution time for creative generation." }, "offerings": { "description": "Offerings available for promotion. Each offering can include creative assets (via portfolio_ref or inline assets) for traditional ads. When si_agent_url is set at the parent level, hosts can offer conversational experiences about any of these offerings.", @@ -122,7 +126,7 @@ }, "product_selectors": { "$ref": "promoted-products.json", - "description": "Selectors to choose which products/offerings from the brand manifest product catalog to promote" + "description": "Selectors to choose which products/offerings from the brand's product catalog to promote" }, "si_agent_url": { "description": "MCP endpoint URL for the brand's SI agent. When present, hosts can connect users to conversational experiences about any of the offerings. The agent handles si_get_offering lookups and full conversations.", @@ -131,7 +135,7 @@ } }, "required": [ - "brand_manifest" + "brand" ], "title": "Promoted Offerings", "type": "object" diff --git a/schemas/cache/core/promoted-products.json b/schemas/cache/core/promoted-products.json index ae3a585f..3ca7563e 100644 --- a/schemas/cache/core/promoted-products.json +++ b/schemas/cache/core/promoted-products.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": true, - "description": "Specification of products or offerings being promoted in a campaign. Supports multiple selection methods from the brand manifest that can be combined using UNION (OR) logic. When multiple selection methods are provided, products matching ANY of the criteria are selected (logical OR, not AND).", + "description": "Specification of products or offerings being promoted in a campaign. Supports multiple selection methods from the brand's product catalog that can be combined using UNION (OR) logic. When multiple selection methods are provided, products matching ANY of the criteria are selected (logical OR, not AND).", "examples": [ { "data": { @@ -19,7 +19,7 @@ "SKU-67890" ] }, - "description": "Direct SKU selection for specific products from brand manifest" + "description": "Direct SKU selection for specific products from brand catalog" }, { "data": { @@ -29,13 +29,13 @@ "sauces" ] }, - "description": "UNION selection: products tagged 'organic' OR 'sauces' OR in 'food/condiments' category from brand manifest" + "description": "UNION selection: products tagged 'organic' OR 'sauces' OR in 'food/condiments' category from brand catalog" }, { "data": { "manifest_query": "all Kraft Heinz pasta sauces under $5" }, - "description": "Natural language product selection from brand manifest" + "description": "Natural language product selection from brand catalog" }, { "data": { @@ -49,7 +49,7 @@ "minProperties": 1, "properties": { "manifest_category": { - "description": "Select products from a specific category in the brand manifest product catalog (e.g., 'beverages/soft-drinks', 'food/sauces')", + "description": "Select products from a specific category in the brand's product catalog (e.g., 'beverages/soft-drinks', 'food/sauces')", "type": "string" }, "manifest_gtins": { @@ -61,18 +61,18 @@ "type": "array" }, "manifest_query": { - "description": "Natural language query to select products from the brand manifest (e.g., 'all Kraft Heinz pasta sauces', 'organic products under $20')", + "description": "Natural language query to select products from the brand's catalog (e.g., 'all pasta sauces', 'organic products under $20')", "type": "string" }, "manifest_skus": { - "description": "Direct product SKU references from the brand manifest product catalog", + "description": "Direct product SKU references from the brand's product catalog", "items": { "type": "string" }, "type": "array" }, "manifest_tags": { - "description": "Select products by tags from the brand manifest product catalog (e.g., 'organic', 'sauces', 'holiday')", + "description": "Select products by tags from the brand's product catalog (e.g., 'organic', 'sauces', 'holiday')", "items": { "type": "string" }, diff --git a/schemas/cache/core/proposal.json b/schemas/cache/core/proposal.json index d80f0d22..9ff1cb0d 100644 --- a/schemas/cache/core/proposal.json +++ b/schemas/cache/core/proposal.json @@ -36,7 +36,7 @@ "type": "string" }, "proposal_id": { - "description": "Unique identifier for this proposal. Used to refine the proposal in subsequent get_products calls or to execute it via create_media_buy.", + "description": "Unique identifier for this proposal. Used to execute it via create_media_buy.", "type": "string" }, "total_budget_guidance": { diff --git a/schemas/cache/core/reference-asset.json b/schemas/cache/core/reference-asset.json new file mode 100644 index 00000000..49b6e843 --- /dev/null +++ b/schemas/cache/core/reference-asset.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "description": "A reference asset that provides creative context. Carries visual materials (mood boards, product shots, example creatives) with semantic roles that tell creative agents how to use them.", + "properties": { + "description": { + "description": "Human-readable description of the asset and how it should inform creative generation", + "type": "string" + }, + "role": { + "description": "How the creative agent should use this asset. style_reference: match the visual style; product_shot: include this product; mood_board: overall look and feel; example_creative: example of a similar execution; logo: logo to use; strategy_doc: strategy or planning document for context", + "enum": [ + "style_reference", + "product_shot", + "mood_board", + "example_creative", + "logo", + "strategy_doc" + ], + "type": "string" + }, + "url": { + "description": "URL to the reference asset (image, video, or document)", + "format": "uri", + "type": "string" + } + }, + "required": [ + "url", + "role" + ], + "title": "Reference Asset", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/core/requirements/promoted-offerings-asset-requirements.json b/schemas/cache/core/requirements/promoted-offerings-asset-requirements.json index 631dcd4a..829fe4ac 100644 --- a/schemas/cache/core/requirements/promoted-offerings-asset-requirements.json +++ b/schemas/cache/core/requirements/promoted-offerings-asset-requirements.json @@ -1,8 +1,18 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": true, - "description": "Requirements for promoted offerings creative assets.", - "properties": {}, + "description": "Requirements for promoted offerings creative assets. Allows formats to declare what content the promoted offerings must provide.", + "properties": { + "requires": { + "description": "Content that must be available in this format's promoted offerings. Each value is a presence check: the referenced field must exist and be non-empty. For brand.* paths, the validating agent resolves the brand reference first.", + "items": { + "$ref": "../../enums/promoted-offerings-requirement.json" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, "title": "Promoted Offerings Asset Requirements", "type": "object" } \ No newline at end of file diff --git a/schemas/cache/creative/asset-types/index.json b/schemas/cache/creative/asset-types/index.json index 02f2bfcb..a20dab38 100644 --- a/schemas/cache/creative/asset-types/index.json +++ b/schemas/cache/creative/asset-types/index.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "adcp_version": "3.0.0-beta.3", + "adcp_version": "latest", "architecture": { "format_aware_validation": { "description": "Creative manifests are validated in the context of their format specification", @@ -89,9 +89,9 @@ "typical_use": "DCO (Dynamic Creative Optimization), real-time personalization, server-side rendering" } }, - "baseUrl": "/schemas/3.0.0-beta.3", + "baseUrl": "/schemas/latest", "description": "Registry of asset types used in AdCP creative manifests. Each asset type defines the structure of actual content payloads (what you send), not requirements or constraints (which belong in format specifications).", - "lastUpdated": "2026-02-12", + "lastUpdated": "2026-02-18", "title": "AdCP Asset Type Registry", "usage_notes": { "creative_manifests": "Creative manifests provide actual asset content, keyed by asset_id from the format. Asset type is determined by the format specification, not declared in the payload.", @@ -100,6 +100,6 @@ }, "version": "1.0.0", "versioning": { - "note": "AdCP uses build-time versioning. This directory contains schemas for AdCP 3.0.0-beta.3. Full semantic versions are available at /schemas/{version}/ (e.g., /schemas/2.5.0/). Major version aliases point to the latest release: /schemas/v3/ \u2192 /schemas/3.0.0-beta.3/." + "note": "AdCP uses build-time versioning. This directory contains schemas for AdCP latest. Full semantic versions are available at /schemas/{version}/ (e.g., /schemas/2.5.0/). Major version aliases point to the latest release: /schemas/vlatest/ \u2192 /schemas/latest/." } } \ No newline at end of file diff --git a/schemas/cache/enums/promoted-offerings-requirement.json b/schemas/cache/enums/promoted-offerings-requirement.json new file mode 100644 index 00000000..de880b9f --- /dev/null +++ b/schemas/cache/enums/promoted-offerings-requirement.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Content requirements that a creative format can impose on promoted offerings. Each value asserts that the referenced content must be present and non-empty. Top-level values (si_agent_url, offerings) are checked directly on the PromotedOfferings object. For brand.* paths, the brand reference must be resolved (looked up from brand.json or registry) before checking the nested field. If the reference cannot be resolved, all brand.* requirements are considered unmet. Paths are limited to two segments.", + "enum": [ + "si_agent_url", + "offerings", + "brand.logos", + "brand.colors", + "brand.tone", + "brand.assets", + "brand.product_catalog" + ], + "title": "Promoted Offerings Requirement", + "type": "string" +} \ No newline at end of file diff --git a/schemas/cache/enums/task-type.json b/schemas/cache/enums/task-type.json index 0aa07046..1c9a9944 100644 --- a/schemas/cache/enums/task-type.json +++ b/schemas/cache/enums/task-type.json @@ -20,7 +20,7 @@ "enumDescriptions": { "activate_signal": "Signals domain: Activate an audience signal on a specific platform or account", "create_media_buy": "Media-buy domain: Create a new advertising campaign with one or more packages", - "create_property_list": "Property domain: Create a new property list with filters and brand manifest", + "create_property_list": "Property domain: Create a new property list with filters and brand reference", "delete_property_list": "Property domain: Delete a property list", "get_creative_delivery": "Creative domain: Retrieve variant-level creative delivery data", "get_property_list": "Property domain: Retrieve a property list with resolved properties", diff --git a/schemas/cache/extensions/index.json b/schemas/cache/extensions/index.json index 75d48d39..38a45a1b 100644 --- a/schemas/cache/extensions/index.json +++ b/schemas/cache/extensions/index.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "_generated": true, - "_generatedAt": "2026-02-12T12:28:49.073Z", + "_generatedAt": "2026-02-18T16:00:53.404Z", "description": "Auto-generated registry of formal AdCP extensions. Extensions provide typed schemas for vendor-specific or domain-specific data within the ext field. Agents declare which extensions they support in their agent card.", "extensions": {}, "title": "AdCP Extension Registry" diff --git a/schemas/cache/media-buy/build-creative-request.json b/schemas/cache/media-buy/build-creative-request.json index ab575837..ceac8389 100644 --- a/schemas/cache/media-buy/build-creative-request.json +++ b/schemas/cache/media-buy/build-creative-request.json @@ -3,9 +3,17 @@ "additionalProperties": true, "description": "Request to transform or generate a creative manifest. Takes a source manifest (which may be minimal for pure generation) and produces a target manifest in the specified format. The source manifest should include all assets required by the target format (e.g., promoted_offerings for generative formats).", "properties": { + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Brand reference for creative generation. Resolved to full brand identity (colors, logos, tone) at execution time." + }, "context": { "$ref": "../core/context.json" }, + "creative_brief": { + "$ref": "../core/creative-brief-ref.json", + "description": "Campaign-level creative brief with objective, audience, messaging, and reference assets. Can be an inline brief object or a URL to a hosted brief. Supplements the natural language message with structured creative direction." + }, "creative_manifest": { "$ref": "../core/creative-manifest.json", "description": "Creative manifest to transform or generate from. For pure generation, this should include the target format_id and any required input assets (e.g., promoted_offerings for generative formats). For transformation (e.g., resizing, reformatting), this is the complete creative to adapt." diff --git a/schemas/cache/media-buy/create-media-buy-request.json b/schemas/cache/media-buy/create-media-buy-request.json index 0a55bcb3..6e08d4fe 100644 --- a/schemas/cache/media-buy/create-media-buy-request.json +++ b/schemas/cache/media-buy/create-media-buy-request.json @@ -82,9 +82,9 @@ ], "type": "object" }, - "brand_manifest": { - "$ref": "../core/brand-manifest-ref.json", - "description": "Brand information manifest serving as the namespace and identity for this media buy. Provides brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest. Can be cached and reused across multiple requests." + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Brand reference for this media buy. Resolved to full brand identity at execution time from brand.json or the registry." }, "buyer_ref": { "description": "Buyer's reference identifier for this media buy", @@ -147,7 +147,7 @@ }, "required": [ "buyer_ref", - "brand_manifest", + "brand", "start_time", "end_time" ], diff --git a/schemas/cache/media-buy/get-products-request.json b/schemas/cache/media-buy/get-products-request.json index 0b250ea6..ea96af6c 100644 --- a/schemas/cache/media-buy/get-products-request.json +++ b/schemas/cache/media-buy/get-products-request.json @@ -3,7 +3,7 @@ "additionalProperties": true, "dependencies": { "product_selectors": [ - "brand_manifest" + "brand" ] }, "description": "Request parameters for discovering available advertising products", @@ -12,12 +12,12 @@ "description": "Account ID for product lookup. Required when the seller declares account.required_for_products = true in capabilities. Returns products with pricing specific to this account's rate card.", "type": "string" }, - "brand_manifest": { - "$ref": "../core/brand-manifest-ref.json", - "description": "Brand information manifest providing brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest." + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Brand reference for product discovery context. Resolved to full brand identity at execution time." }, "brief": { - "description": "Natural language description of campaign requirements. When refining a proposal, can include instructions like 'focus more on German speakers' or 'increase mobile allocation'.", + "description": "Natural language description of campaign requirements.", "type": "string" }, "context": { @@ -34,15 +34,11 @@ }, "product_selectors": { "$ref": "../core/promoted-products.json", - "description": "Selectors to filter the brand manifest product catalog for product discovery. When provided, sellers should only return advertising products where the selected catalog items have matches. Uses the same selection methods as promoted-offerings." + "description": "Selectors to filter the brand's product catalog for product discovery. When provided, sellers should only return advertising products where the selected catalog items have matches. Uses the same selection methods as promoted-offerings." }, "property_list": { "$ref": "../core/property-list-ref.json", "description": "[AdCP 3.0] Reference to an externally managed property list. When provided, the sales agent should filter products to only those available on properties in the list." - }, - "proposal_id": { - "description": "Optional proposal ID to refine. When provided with a brief, the publisher will use the brief as refinement instructions for the specified proposal and return an updated version.", - "type": "string" } }, "required": [], diff --git a/schemas/cache/media-buy/get-products-response.json b/schemas/cache/media-buy/get-products-response.json index 4851500f..8bdd8d7f 100644 --- a/schemas/cache/media-buy/get-products-response.json +++ b/schemas/cache/media-buy/get-products-response.json @@ -35,7 +35,7 @@ "type": "boolean" }, "proposals": { - "description": "Optional array of proposed media plans with budget allocations across products. Publishers include proposals when they can provide strategic guidance based on the brief. Proposals are actionable - buyers can refine them via subsequent get_products calls or execute them directly via create_media_buy.", + "description": "Optional array of proposed media plans with budget allocations across products. Publishers include proposals when they can provide strategic guidance based on the brief. Proposals are actionable - buyers can refine them via follow-up get_products calls within the same session, or execute them directly via create_media_buy.", "items": { "$ref": "../core/proposal.json" }, diff --git a/schemas/cache/media-buy/sync-creatives-request.json b/schemas/cache/media-buy/sync-creatives-request.json index 353ad90e..2527d7ec 100644 --- a/schemas/cache/media-buy/sync-creatives-request.json +++ b/schemas/cache/media-buy/sync-creatives-request.json @@ -45,12 +45,8 @@ "content": "Create a warm, festive holiday campaign featuring winter products" }, "promoted_offerings": { - "brand_manifest": { - "colors": { - "primary": "#C41E3A", - "secondary": "#165B33" - }, - "url": "https://retailer.com" + "brand": { + "domain": "acmeretailer.com" } } }, diff --git a/schemas/cache/property/create-property-list-request.json b/schemas/cache/property/create-property-list-request.json index e92c8673..b20ec9e5 100644 --- a/schemas/cache/property/create-property-list-request.json +++ b/schemas/cache/property/create-property-list-request.json @@ -11,9 +11,9 @@ "minItems": 1, "type": "array" }, - "brand_manifest": { - "$ref": "../core/brand-manifest.json", - "description": "Brand identity and requirements. When provided, the agent automatically applies appropriate rules based on brand characteristics (industry, target_audience, etc.)." + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Brand reference. When provided, the agent automatically applies appropriate rules based on brand characteristics (industry, target_audience, etc.). Resolved at execution time." }, "context": { "$ref": "../core/context.json" diff --git a/schemas/cache/property/property-list.json b/schemas/cache/property/property-list.json index 17b1ba82..59f189ca 100644 --- a/schemas/cache/property/property-list.json +++ b/schemas/cache/property/property-list.json @@ -10,9 +10,9 @@ }, "type": "array" }, - "brand_manifest": { - "$ref": "../core/brand-manifest.json", - "description": "Brand identity used to automatically apply appropriate rules" + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Brand reference used to automatically apply appropriate rules. Resolved to full brand identity at execution time." }, "cache_duration_hours": { "default": 24, diff --git a/schemas/cache/property/update-property-list-request.json b/schemas/cache/property/update-property-list-request.json index 91ff96a0..948e179f 100644 --- a/schemas/cache/property/update-property-list-request.json +++ b/schemas/cache/property/update-property-list-request.json @@ -10,9 +10,9 @@ }, "type": "array" }, - "brand_manifest": { - "$ref": "../core/brand-manifest.json", - "description": "Update brand identity and requirements" + "brand": { + "$ref": "../core/brand-ref.json", + "description": "Update brand reference. Resolved to full brand identity at execution time." }, "context": { "$ref": "../core/context.json" diff --git a/schemas/cache/protocol/get-adcp-capabilities-response.json b/schemas/cache/protocol/get-adcp-capabilities-response.json index 8ca307af..c293b7f4 100644 --- a/schemas/cache/protocol/get-adcp-capabilities-response.json +++ b/schemas/cache/protocol/get-adcp-capabilities-response.json @@ -70,6 +70,17 @@ "context": { "$ref": "../core/context.json" }, + "creative": { + "additionalProperties": true, + "description": "Creative protocol capabilities. Only present if creative is in supported_protocols.", + "properties": { + "supports_brief": { + "description": "Whether this creative agent accepts creative_brief in build_creative requests for structured campaign-level creative direction", + "type": "boolean" + } + }, + "type": "object" + }, "errors": { "description": "Task-specific errors and warnings", "items": { @@ -467,8 +478,8 @@ "sponsored_intelligence": { "description": "Sponsored Intelligence protocol capabilities. Only present if sponsored_intelligence is in supported_protocols. SI agents handle conversational brand experiences.", "properties": { - "brand_manifest_url": { - "description": "URL to brand manifest with colors, fonts, logos, tone", + "brand_url": { + "description": "URL to brand.json with colors, fonts, logos, tone", "format": "uri", "type": "string" }, diff --git a/scripts/consolidate_exports.py b/scripts/consolidate_exports.py index a9412b02..e5b831f0 100644 --- a/scripts/consolidate_exports.py +++ b/scripts/consolidate_exports.py @@ -193,6 +193,22 @@ def generate_consolidated_exports() -> str: lines.extend(alias_lines) + # Add backwards-compat stub for BrandManifest (removed from upstream schemas in latest). + # Kept as a permissive model so existing code importing it continues to work. + compat_lines = [ + "", + "# Backwards-compat: BrandManifest was removed from upstream schemas.", + "# Kept as a permissive model so existing code importing it continues to work.", + "from adcp.types.base import AdCPBaseModel as _AdCPBaseModel", + "from pydantic import ConfigDict as _ConfigDict", + "", + "class BrandManifest(_AdCPBaseModel):", + ' model_config = _ConfigDict(extra="allow")', + "", + ] + lines.extend(compat_lines) + all_exports_with_aliases = all_exports_with_aliases | {"BrandManifest"} + # Format __all__ list with proper line breaks (max 100 chars per line) exports_list = sorted(list(all_exports_with_aliases)) all_lines = ["", "# Explicit exports", "__all__ = ["] @@ -226,14 +242,12 @@ def generate_consolidated_exports() -> str: rebuild_lines = [ "", "# Rebuild models with forward references", - "# This must happen AFTER all imports to resolve module-qualified type references", - "# like brand_manifest.BrandManifest used in generated code", + "# This must happen AFTER all imports to resolve forward reference chains", "", "# Import individual modules needed for rebuilding", "from adcp.types import generated_poc", "", "# Rebuild models that reference other models via forward refs", - "BrandManifest.model_rebuild()", "PromotedOfferings.model_rebuild()", "CreativeManifest.model_rebuild()", "PreviewCreativeRequest1.model_rebuild()", @@ -259,21 +273,25 @@ def main(): print(f"\nWriting {OUTPUT_FILE}...") OUTPUT_FILE.write_text(content) - # Run black to format the generated file + # Run black to format the generated file. + # Try uv run first (works in the project virtualenv), then fall back to sys.executable. print("Formatting with black...") - try: - result = subprocess.run( - [sys.executable, "-m", "black", str(OUTPUT_FILE), "--quiet"], - capture_output=True, - text=True, - check=False, - ) - if result.returncode == 0: - print("✓ Formatted with black") - else: - print(f"⚠ Black formatting had issues: {result.stderr}") - except Exception as e: - print(f"⚠ Could not run black (not critical): {e}") + black_commands = [ + ["uv", "run", "black", str(OUTPUT_FILE), "--quiet"], + [sys.executable, "-m", "black", str(OUTPUT_FILE), "--quiet"], + ] + formatted = False + for cmd in black_commands: + try: + result = subprocess.run(cmd, capture_output=True, text=True, check=False) + if result.returncode == 0: + print("✓ Formatted with black") + formatted = True + break + except FileNotFoundError: + continue + if not formatted: + print("⚠ Could not format with black (not installed)") print("✓ Successfully generated consolidated exports") export_count = len( diff --git a/scripts/post_generate_fixes.py b/scripts/post_generate_fixes.py index bc6489ec..bda2ed70 100644 --- a/scripts/post_generate_fixes.py +++ b/scripts/post_generate_fixes.py @@ -257,6 +257,44 @@ def add_deprecated_field_metadata(): print(" No deprecated fields needed fixing") +def fix_constr_type_annotations(): + """Replace constr(pattern=...) with Annotated[str, StringConstraints(pattern=...)] in generated files. + + datamodel-code-generator uses constr(pattern=...) as dict key types, but mypy's + Pydantic v2 plugin rejects this form. The correct form is Annotated[str, StringConstraints(...)]. + """ + fixed_count = 0 + + for py_file in OUTPUT_DIR.rglob("*.py"): + with open(py_file) as f: + content = f.read() + + if "constr(pattern=" not in content: + continue + + original = content + + # Replace constr(pattern=r'...') with Annotated[str, StringConstraints(pattern=r'...')] + content = re.sub( + r"constr\(pattern=(r'[^']*')\)", + r"Annotated[str, StringConstraints(pattern=\1)]", + content, + ) + + # Replace 'constr' in imports with 'StringConstraints' + content = re.sub(r"\bconstr\b", "StringConstraints", content) + + if content != original: + with open(py_file, "w") as f: + f.write(content) + fixed_count += 1 + + if fixed_count > 0: + print(f" Replaced constr(pattern=...) with StringConstraints in {fixed_count} file(s)") + else: + print(" No constr(pattern=...) annotations needed fixing") + + def main(): """Apply all post-generation fixes.""" print("Applying post-generation fixes...") @@ -267,6 +305,7 @@ def main(): fix_enum_defaults() fix_preview_creative_request_discriminator() add_deprecated_field_metadata() + fix_constr_type_annotations() print("\n✓ Post-generation fixes complete\n") diff --git a/src/adcp/ADCP_VERSION b/src/adcp/ADCP_VERSION index f5970430..a0f9a4b4 100644 --- a/src/adcp/ADCP_VERSION +++ b/src/adcp/ADCP_VERSION @@ -1 +1 @@ -3.0.0-beta.3 +latest diff --git a/src/adcp/__init__.py b/src/adcp/__init__.py index 0d4cc113..2bb05f37 100644 --- a/src/adcp/__init__.py +++ b/src/adcp/__init__.py @@ -207,6 +207,7 @@ ) from adcp.types.core import ( AgentConfig, + Member, Protocol, ResolvedBrand, ResolvedProperty, @@ -272,6 +273,7 @@ def get_adcp_version() -> str: "RegistryClient", # Core types "AgentConfig", + "Member", "Protocol", "ResolvedBrand", "ResolvedProperty", diff --git a/src/adcp/registry.py b/src/adcp/registry.py index f5493f39..ac77c97d 100644 --- a/src/adcp/registry.py +++ b/src/adcp/registry.py @@ -1,6 +1,6 @@ -from __future__ import annotations +"""Client for the AdCP registry API (brand, property, and member lookups).""" -"""Client for the AdCP registry API (brand and property lookups).""" +from __future__ import annotations import asyncio from typing import Any @@ -9,7 +9,7 @@ from pydantic import ValidationError from adcp.exceptions import RegistryError -from adcp.types.core import ResolvedBrand, ResolvedProperty +from adcp.types.core import Member, ResolvedBrand, ResolvedProperty DEFAULT_REGISTRY_URL = "https://agenticadvertising.org" MAX_BULK_DOMAINS = 100 @@ -18,7 +18,7 @@ class RegistryClient: """Client for the AdCP registry API. - Provides brand and property lookups against the central AdCP registry. + Provides brand, property, and member lookups against the central AdCP registry. Args: base_url: Registry API base URL. @@ -67,16 +67,22 @@ async def __aexit__(self, *args: Any) -> None: await self.close() async def lookup_brand(self, domain: str) -> ResolvedBrand | None: - """Resolve a single domain to its canonical brand identity. + """Resolve a domain to its brand identity. + + Works for any domain — brand houses, sub-brands, and operators + (agencies, DSPs) are all brands in the registry. Args: - domain: Domain to resolve (e.g., "nike.com"). + domain: Domain to resolve (e.g., "nike.com", "wpp.com"). Returns: - ResolvedBrand if found, None if the domain is not in the registry. + ResolvedBrand if found, None if not in the registry. Raises: RegistryError: On HTTP or parsing errors. + + Example: + brand = await registry.lookup_brand(request.brand.domain) """ client = await self._get_client() try: @@ -131,14 +137,11 @@ async def lookup_brands( ] chunk_results = await asyncio.gather( - *[self._lookup_brands_chunk(chunk) for chunk in chunks], - return_exceptions=True, + *[self._lookup_brands_chunk(chunk) for chunk in chunks] ) merged: dict[str, ResolvedBrand | None] = {} for result in chunk_results: - if isinstance(result, BaseException): - raise result merged.update(result) return merged @@ -244,14 +247,11 @@ async def lookup_properties( ] chunk_results = await asyncio.gather( - *[self._lookup_properties_chunk(chunk) for chunk in chunks], - return_exceptions=True, + *[self._lookup_properties_chunk(chunk) for chunk in chunks] ) merged: dict[str, ResolvedProperty | None] = {} for result in chunk_results: - if isinstance(result, BaseException): - raise result merged.update(result) return merged @@ -288,6 +288,82 @@ async def _lookup_properties_chunk( except httpx.HTTPError as e: raise RegistryError(f"Bulk property lookup failed: {e}") from e except (ValidationError, ValueError) as e: - raise RegistryError( - f"Bulk property lookup failed: invalid response: {e}" - ) from e + raise RegistryError(f"Bulk property lookup failed: invalid response: {e}") from e + + async def list_members(self, limit: int = 100) -> list[Member]: + """List organizations registered in the AAO member directory. + + Args: + limit: Maximum number of members to return. + + Returns: + List of Member objects. + + Raises: + RegistryError: On HTTP or parsing errors. + """ + if limit < 1: + raise ValueError(f"limit must be at least 1, got {limit}") + + client = await self._get_client() + try: + response = await client.get( + f"{self._base_url}/api/members", + params={"limit": limit}, + headers={"User-Agent": self._user_agent}, + timeout=self._timeout, + ) + if response.status_code != 200: + raise RegistryError( + f"Member list failed: HTTP {response.status_code}", + status_code=response.status_code, + ) + data = response.json() + return [Member.model_validate(m) for m in data.get("members", [])] + except RegistryError: + raise + except httpx.TimeoutException as e: + raise RegistryError(f"Member list timed out after {self._timeout}s") from e + except httpx.HTTPError as e: + raise RegistryError(f"Member list failed: {e}") from e + except (ValidationError, ValueError) as e: + raise RegistryError(f"Member list failed: invalid response: {e}") from e + + async def get_member(self, slug: str) -> Member | None: + """Get a single AAO member by their slug. + + Args: + slug: Member slug (e.g., "adgentek"). + + Returns: + Member if found, None if not in the registry. + + Raises: + RegistryError: On HTTP or parsing errors. + """ + client = await self._get_client() + try: + response = await client.get( + f"{self._base_url}/api/members/{slug}", + headers={"User-Agent": self._user_agent}, + timeout=self._timeout, + ) + if response.status_code == 404: + return None + if response.status_code != 200: + raise RegistryError( + f"Member lookup failed: HTTP {response.status_code}", + status_code=response.status_code, + ) + data = response.json() + if data is None: + return None + return Member.model_validate(data) + except RegistryError: + raise + except httpx.TimeoutException as e: + raise RegistryError(f"Member lookup timed out after {self._timeout}s") from e + except httpx.HTTPError as e: + raise RegistryError(f"Member lookup failed: {e}") from e + except (ValidationError, ValueError) as e: + raise RegistryError(f"Member lookup failed: invalid response: {e}") from e diff --git a/src/adcp/types/__init__.py b/src/adcp/types/__init__.py index a134eb6f..1bd07839 100644 --- a/src/adcp/types/__init__.py +++ b/src/adcp/types/__init__.py @@ -356,6 +356,7 @@ # Users should import TaskStatus from adcp.types.core directly if they need the core enum from adcp.types.core import ( AgentConfig, + Member, Protocol, ResolvedBrand, ResolvedProperty, @@ -643,6 +644,7 @@ "WebhookAsset", # Core types "AgentConfig", + "Member", "Protocol", "ResolvedBrand", "ResolvedProperty", diff --git a/src/adcp/types/_generated.py b/src/adcp/types/_generated.py index c5bad4c6..41779043 100644 --- a/src/adcp/types/_generated.py +++ b/src/adcp/types/_generated.py @@ -10,7 +10,7 @@ DO NOT EDIT MANUALLY. Generated from: https://github.com/adcontextprotocol/adcp/tree/main/schemas -Generation date: 2026-02-12 12:49:35 UTC +Generation date: 2026-02-18 21:17:48 UTC """ # ruff: noqa: E501, I001 @@ -55,9 +55,9 @@ AgenticCheckout, Architecture, Asset, - AssetType, AuthorizedOperator, Avatar, + Background, Brand, Brand1, BrandAgent, @@ -72,6 +72,7 @@ ColorValue2, ColorValue2Item, Colors, + Contact1, Country, Disclaimer, Domain, @@ -81,6 +82,7 @@ KellerType, LocalizedName, Logo, + Orientation, ProductCatalog, Property, Store, @@ -88,6 +90,7 @@ Trademark, Type, UpdateFrequency, + Variant, Voice, ) from adcp.types.generated_poc.content_standards.artifact import ( @@ -213,32 +216,12 @@ from adcp.types.generated_poc.core.assets.webhook_asset import Security, WebhookAsset from adcp.types.generated_poc.core.async_response_data import AdcpAsyncResponseData from adcp.types.generated_poc.core.attribution_window import AttributionWindow -from adcp.types.generated_poc.core.brand_manifest import ( - Accent, - Accent1, - Accent1Item, - Background, - Background1, - Background1Item, - Background2, - BrandManifest, - Orientation, - Primary, - Primary1, - Primary1Item, - Secondary, - Secondary1, - Secondary1Item, - Text, - Text1, - Text1Item, - Variant, -) -from adcp.types.generated_poc.core.brand_manifest_ref import BrandManifestReference from adcp.types.generated_poc.core.brand_ref import BrandReference from adcp.types.generated_poc.core.context import ContextObject from adcp.types.generated_poc.core.creative_asset import CreativeAsset, Input from adcp.types.generated_poc.core.creative_assignment import CreativeAssignment +from adcp.types.generated_poc.core.creative_brief import CreativeBrief, Messaging, Objective +from adcp.types.generated_poc.core.creative_brief_ref import CreativeBriefReference from adcp.types.generated_poc.core.creative_filters import CreativeFilters from adcp.types.generated_poc.core.creative_manifest import CreativeManifest from adcp.types.generated_poc.core.creative_policy import CreativePolicy @@ -344,7 +327,11 @@ Region, RequiredGeoTargetingItem, ) -from adcp.types.generated_poc.core.promoted_offerings import AssetSelectors, PromotedOfferings +from adcp.types.generated_poc.core.promoted_offerings import ( + AssetSelectors, + AssetType, + PromotedOfferings, +) from adcp.types.generated_poc.core.promoted_products import ManifestGtin, PromotedProducts from adcp.types.generated_poc.core.property_id import PropertyId from adcp.types.generated_poc.core.property_list_ref import PropertyListReference @@ -361,6 +348,7 @@ Authentication, PushNotificationConfig, ) +from adcp.types.generated_poc.core.reference_asset import ReferenceAsset from adcp.types.generated_poc.core.reporting_capabilities import ( DateRangeSupport, ReportingCapabilities, @@ -536,6 +524,9 @@ from adcp.types.generated_poc.enums.postal_system import PostalCodeSystem from adcp.types.generated_poc.enums.preview_output_format import PreviewOutputFormat from adcp.types.generated_poc.enums.pricing_model import PricingModel +from adcp.types.generated_poc.enums.promoted_offerings_requirement import ( + PromotedOfferingsRequirement, +) from adcp.types.generated_poc.enums.property_type import PropertyType from adcp.types.generated_poc.enums.publisher_identifier_types import PublisherIdentifierTypes from adcp.types.generated_poc.enums.reach_unit import ReachUnit @@ -851,14 +842,21 @@ # Special imports for name collisions (qualified names for types defined in multiple modules) from adcp.types.generated_poc.core.package import Package as _PackageFromPackage +# Backwards-compat: BrandManifest was removed from upstream schemas. +# Kept as a permissive model so existing code importing it continues to work. +from adcp.types.base import AdCPBaseModel as _AdCPBaseModel +from pydantic import ConfigDict as _ConfigDict + + +class BrandManifest(_AdCPBaseModel): + model_config = _ConfigDict(extra="allow") + + # Explicit exports __all__ = [ "A2UiComponent", "A2UiSurface", "A2ui", - "Accent", - "Accent1", - "Accent1Item", "Accessibility", "Account", "AcpHandoff", @@ -946,9 +944,6 @@ "AvailableMetric", "Avatar", "Background", - "Background1", - "Background1Item", - "Background2", "BaseGroupAsset", "BaseIndividualAsset", "BasePropertySource", @@ -969,7 +964,6 @@ "BrandDiscovery4", "BrandId", "BrandManifest", - "BrandManifestReference", "BrandReference", "BudgetRange", "BudgetRange1", @@ -1004,6 +998,7 @@ "Components", "ConsentScopeEnum", "Contact", + "Contact1", "Container", "Content", "ContentStandards", @@ -1038,6 +1033,8 @@ "CreativeAgentCapability", "CreativeAsset", "CreativeAssignment", + "CreativeBrief", + "CreativeBriefReference", "CreativeFilters", "CreativeManifest", "CreativePolicy", @@ -1223,6 +1220,7 @@ "MediaBuyFeatures", "MediaBuyStatus", "MediaChannel", + "Messaging", "Metadata", "Method", "MetricType", @@ -1233,6 +1231,7 @@ "MoovAtomPosition", "MraidVersion", "NotificationType", + "Objective", "Offering", "OptimizationGoal", "Orientation", @@ -1275,9 +1274,6 @@ "Pricing", "PricingModel", "PricingOption", - "Primary", - "Primary1", - "Primary1Item", "PrimaryCountry", "PrivacyPolicyAcknowledged", "Product", @@ -1288,6 +1284,7 @@ "ProductFilters", "PromotedOfferings", "PromotedOfferingsAssetRequirements", + "PromotedOfferingsRequirement", "PromotedProducts", "Property", "PropertyError", @@ -1325,6 +1322,7 @@ "ReachUnit", "Reason", "Record", + "ReferenceAsset", "Region", "Renders", "Renders1", @@ -1347,9 +1345,6 @@ "Sandbox", "ScanType", "Scope", - "Secondary", - "Secondary1", - "Secondary1Item", "Security", "SelectionMode", "SessionStatus", @@ -1425,9 +1420,6 @@ "TaskStatus", "TaskType", "TerminationContext", - "Text", - "Text1", - "Text1Item", "TextAsset", "TextAssetRequirements", "TimeBasedPricingOption", @@ -1503,14 +1495,12 @@ # Rebuild models with forward references -# This must happen AFTER all imports to resolve module-qualified type references -# like brand_manifest.BrandManifest used in generated code +# This must happen AFTER all imports to resolve forward reference chains # Import individual modules needed for rebuilding from adcp.types import generated_poc # Rebuild models that reference other models via forward refs -BrandManifest.model_rebuild() PromotedOfferings.model_rebuild() CreativeManifest.model_rebuild() PreviewCreativeRequest1.model_rebuild() diff --git a/src/adcp/types/core.py b/src/adcp/types/core.py index 525591b9..a1ce5e0c 100644 --- a/src/adcp/types/core.py +++ b/src/adcp/types/core.py @@ -1,11 +1,11 @@ -from __future__ import annotations - """Core type definitions.""" +from __future__ import annotations + from enum import Enum from typing import Any, Generic, Literal, TypeVar -from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator class Protocol(str, Enum): @@ -188,9 +188,47 @@ class ResolvedBrand(BaseModel): house_domain: str | None = None house_name: str | None = None brand_agent_url: str | None = None + brand: dict[str, Any] | None = None brand_manifest: dict[str, Any] | None = None source: str + @model_validator(mode="before") + @classmethod + def _normalize_brand_fields(cls, data: Any) -> Any: + """Cross-populate brand and brand_manifest so both names are always accessible.""" + if isinstance(data, dict): + data = dict(data) + if "brand" in data and "brand_manifest" not in data: + data["brand_manifest"] = data["brand"] + elif "brand_manifest" in data and "brand" not in data: + data["brand"] = data["brand_manifest"] + return data + + +class Member(BaseModel): + """An organization registered in the AAO member directory.""" + + model_config = ConfigDict(extra="allow") + + id: str + slug: str + display_name: str + description: str | None = None + tagline: str | None = None + logo_url: str | None = None + logo_light_url: str | None = None + logo_dark_url: str | None = None + contact_email: str | None = None + contact_website: str | None = None + offerings: list[str] = Field(default_factory=list) + markets: list[str] = Field(default_factory=list) + agents: list[dict[str, Any]] = Field(default_factory=list) + brands: list[dict[str, Any]] = Field(default_factory=list) + is_public: bool = True + is_founding_member: bool = False + featured: bool = False + si_enabled: bool = False + class ResolvedProperty(BaseModel): """Property information resolved from the AdCP registry.""" diff --git a/src/adcp/types/generated_poc/adagents.py b/src/adcp/types/generated_poc/adagents.py index 2e248311..1eb94f89 100644 --- a/src/adcp/types/generated_poc/adagents.py +++ b/src/adcp/types/generated_poc/adagents.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: adagents.json -# timestamp: 2026-02-12T12:49:35+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -363,12 +363,12 @@ class AdcpAgentsAuthorization(RootModel[AdcpAgentsAuthorization1 | AdcpAgentsAut 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-beta.3/adagents.json', + '$schema': '/schemas/latest/adagents.json', 'authoritative_location': 'https://cdn.example.com/adagents/v2/adagents.json', 'last_updated': '2025-01-15T10:00:00Z', }, { - '$schema': '/schemas/3.0.0-beta.3/adagents.json', + '$schema': '/schemas/latest/adagents.json', 'authorized_agents': [ { 'authorization_type': 'property_tags', @@ -394,7 +394,7 @@ class AdcpAgentsAuthorization(RootModel[AdcpAgentsAuthorization1 | AdcpAgentsAut }, }, { - '$schema': '/schemas/3.0.0-beta.3/adagents.json', + '$schema': '/schemas/latest/adagents.json', 'authorized_agents': [ { 'authorization_type': 'property_tags', @@ -463,7 +463,7 @@ class AdcpAgentsAuthorization(RootModel[AdcpAgentsAuthorization1 | AdcpAgentsAut }, }, { - '$schema': '/schemas/3.0.0-beta.3/adagents.json', + '$schema': '/schemas/latest/adagents.json', 'authorized_agents': [ { 'authorization_type': 'property_tags', @@ -491,7 +491,7 @@ class AdcpAgentsAuthorization(RootModel[AdcpAgentsAuthorization1 | AdcpAgentsAut }, }, { - '$schema': '/schemas/3.0.0-beta.3/adagents.json', + '$schema': '/schemas/latest/adagents.json', 'authorized_agents': [ { 'authorization_type': 'publisher_properties', @@ -531,7 +531,7 @@ class AdcpAgentsAuthorization(RootModel[AdcpAgentsAuthorization1 | AdcpAgentsAut 'last_updated': '2025-01-10T17:00:00Z', }, { - '$schema': '/schemas/3.0.0-beta.3/adagents.json', + '$schema': '/schemas/latest/adagents.json', 'authorized_agents': [ { 'authorization_type': 'property_tags', @@ -589,7 +589,7 @@ class AdcpAgentsAuthorization(RootModel[AdcpAgentsAuthorization1 | AdcpAgentsAut }, }, { - '$schema': '/schemas/3.0.0-beta.3/adagents.json', + '$schema': '/schemas/latest/adagents.json', 'authorized_agents': [ { 'authorization_type': 'signal_tags', diff --git a/src/adcp/types/generated_poc/brand.py b/src/adcp/types/generated_poc/brand.py index ccd832cf..2f47b09e 100644 --- a/src/adcp/types/generated_poc/brand.py +++ b/src/adcp/types/generated_poc/brand.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand.json -# timestamp: 2026-02-12T12:49:35+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -10,6 +10,8 @@ from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, AwareDatetime, ConfigDict, EmailStr, Field, RootModel +from .enums import asset_content_type + class BrandDiscovery1(AdCPBaseModel): model_config = ConfigDict( @@ -31,29 +33,33 @@ class Trademark(AdCPBaseModel): registry: str -class AssetType(Enum): - image = 'image' - video = 'video' - audio = 'audio' - text = 'text' - - class Asset(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) asset_id: Annotated[str, Field(description='Unique identifier')] - asset_type: Annotated[AssetType, Field(description='Asset type')] - duration_seconds: float | None = None - format: Annotated[str | None, Field(description='File format (jpg, mp4, etc.)')] = None - height: int | None = None + asset_type: Annotated[ + asset_content_type.AssetContentType, Field(description='Type of asset content') + ] + description: Annotated[str | None, Field(description='Asset description or usage notes')] = None + duration_seconds: Annotated[ + float | None, Field(description='Video/audio duration in seconds') + ] = None + file_size_bytes: Annotated[int | None, Field(description='File size in bytes')] = None + format: Annotated[str | None, Field(description="File format (e.g., 'jpg', 'mp4', 'mp3')")] = ( + None + ) + height: Annotated[int | None, Field(description='Image/video height in pixels')] = None + metadata: Annotated[ + dict[str, Any] | None, Field(description='Additional asset-specific metadata') + ] = None name: Annotated[str | None, Field(description='Human-readable name')] = None tags: Annotated[ list[str] | None, - Field(description="Tags for discovery (e.g., 'hero', 'lifestyle', 'product')"), + Field(description="Tags for discovery (e.g., 'hero', 'lifestyle', 'product', 'holiday')"), ] = None - url: Annotated[AnyUrl, Field(description='URL to asset')] - width: int | None = None + url: Annotated[AnyUrl, Field(description='URL to CDN-hosted asset file')] + width: Annotated[int | None, Field(description='Image/video width in pixels')] = None class Brand1(RootModel[str]): @@ -73,6 +79,11 @@ class Avatar(AdCPBaseModel): settings: dict[str, Any] | None = None +class Contact1(AdCPBaseModel): + email: Annotated[EmailStr | None, Field(description='Contact email')] = None + phone: Annotated[str | None, Field(description='Contact phone number')] = None + + class Disclaimer(AdCPBaseModel): context: str | None = None required: bool | None = True @@ -193,22 +204,74 @@ class LocalizedName(RootModel[dict[str, str]]): root: Annotated[dict[str, str], Field(min_length=1)] +class Background(Enum): + dark_bg = 'dark-bg' + light_bg = 'light-bg' + transparent_bg = 'transparent-bg' + + +class Orientation(Enum): + square = 'square' + horizontal = 'horizontal' + vertical = 'vertical' + stacked = 'stacked' + + +class Variant(Enum): + primary = 'primary' + secondary = 'secondary' + icon = 'icon' + wordmark = 'wordmark' + full_lockup = 'full-lockup' + + class Logo(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) + background: Annotated[ + Background | None, + Field( + description='Background compatibility. dark-bg: use on dark backgrounds, light-bg: use on light backgrounds, transparent-bg: has transparent background' + ), + ] = None height: Annotated[int | None, Field(description='Height in pixels')] = None + orientation: Annotated[ + Orientation | None, + Field( + description='Logo aspect ratio orientation. square: ~1:1, horizontal: wide, vertical: tall, stacked: vertically arranged elements' + ), + ] = None tags: Annotated[ list[str] | None, - Field(description="Semantic tags (e.g., 'dark', 'light', 'square', 'horizontal', 'icon')"), + Field( + description='Additional semantic tags for custom categorization beyond the standard orientation, background, and variant fields' + ), ] = None url: Annotated[AnyUrl, Field(description='URL to the logo asset')] + usage: Annotated[ + str | None, + Field( + description="Human-readable description of when to use this logo variant (e.g., 'Primary logo for use on light backgrounds')" + ), + ] = None + variant: Annotated[ + Variant | None, + Field( + description='Logo variant type. primary: main logo, secondary: alternative, icon: symbol only, wordmark: text only, full-lockup: complete logo' + ), + ] = None width: Annotated[int | None, Field(description='Width in pixels')] = None class AgenticCheckout(AdCPBaseModel): - endpoint: AnyUrl - spec: Literal['openai_agentic_checkout_v1'] + endpoint: Annotated[AnyUrl, Field(description='Base URL for checkout session API')] + spec: Annotated[ + Literal['openai_agentic_checkout_v1'], Field(description='Checkout API specification') + ] + supported_payment_providers: Annotated[ + list[str] | None, Field(description='Payment providers supported by this checkout endpoint') + ] = None class FeedFormat(Enum): @@ -229,11 +292,22 @@ class ProductCatalog(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) - agentic_checkout: AgenticCheckout | None = None - categories: list[str] | None = None - feed_format: FeedFormat | None = None - feed_url: AnyUrl - update_frequency: UpdateFrequency | None = None + agentic_checkout: Annotated[ + AgenticCheckout | None, Field(description='Agentic checkout endpoint configuration') + ] = None + categories: Annotated[ + list[str] | None, Field(description='Product categories available in the catalog') + ] = None + feed_format: Annotated[FeedFormat | None, Field(description='Format of the product feed')] = ( + None + ) + feed_url: Annotated[AnyUrl, Field(description='URL to product catalog feed')] + last_updated: Annotated[ + AwareDatetime | None, Field(description='When the product catalog was last updated') + ] = None + update_frequency: Annotated[ + UpdateFrequency | None, Field(description='How frequently the product catalog is updated') + ] = None class Store(Enum): @@ -327,12 +401,10 @@ class Brand(AdCPBaseModel): assets: Annotated[list[Asset] | None, Field(description='Brand asset library')] = None avatar: Annotated[Avatar | None, Field(description='Visual avatar configuration')] = None brand_agent: Annotated[ - BrandAgent | None, - Field( - description='Brand agent that provides dynamic brand manifest data. Agent implements get_brand_manifest({ house, brand_id }).' - ), + BrandAgent | None, Field(description='Brand agent that provides dynamic brand data via MCP') ] = None colors: Colors | None = None + contact: Annotated[Contact1 | None, Field(description='Brand-level contact information')] = None description: Annotated[str | None, Field(description='Brand description')] = None disclaimers: Annotated[ list[Disclaimer] | None, Field(description='Legal disclaimers for creatives') @@ -368,6 +440,9 @@ class Brand(AdCPBaseModel): tone: Annotated[ str | Tone | None, Field(description='Brand voice and messaging tone guidelines') ] = None + url: Annotated[ + AnyUrl | None, Field(description='Primary brand URL for context and asset discovery') + ] = None voice: Annotated[Voice | None, Field(description='TTS voice configuration')] = None @@ -437,33 +512,44 @@ class BrandDiscovery( 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-beta.3/brand.json', + '$schema': '/schemas/latest/brand.json', 'authoritative_location': 'https://adcontextprotocol.org/brand/abc123/brand.json', }, { - '$schema': '/schemas/3.0.0-beta.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-beta.3/brand.json', + '$schema': '/schemas/latest/brand.json', 'brand_agent': {'id': 'acme_brand_agent', 'url': 'https://agent.acme.com/mcp'}, 'version': '1.0', }, { - '$schema': '/schemas/3.0.0-beta.3/brand.json', + '$schema': '/schemas/latest/brand.json', 'brands': [ { 'colors': {'primary': '#FF6600', 'secondary': '#0066CC'}, + 'contact': {'email': 'brands@pg.com'}, 'description': 'Laundry detergent brand', 'id': 'tide', 'industry': 'cpg', 'keller_type': 'master', 'logos': [ { - 'tags': ['square', 'primary'], + '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', + }, ], 'names': [{'en': 'Tide'}, {'es': 'Tide'}, {'zh': '汰渍'}], 'properties': [ @@ -481,6 +567,7 @@ class BrandDiscovery( 'dos': ['Use simple, direct language', 'Emphasize cleaning power'], 'voice': 'clean, fresh, trustworthy', }, + 'url': 'https://tide.com', }, { 'colors': {'primary': '#00A0D2'}, @@ -488,12 +575,17 @@ class BrandDiscovery( 'industry': 'cpg', 'keller_type': 'master', 'logos': [ - {'tags': ['primary'], 'url': 'https://cdn.pg.com/pampers/logo.png'} + { + 'orientation': 'horizontal', + 'url': 'https://cdn.pg.com/pampers/logo.png', + 'variant': 'primary', + } ], 'names': [{'en': 'Pampers'}], 'properties': [ {'identifier': 'pampers.com', 'primary': True, 'type': 'website'} ], + 'url': 'https://pampers.com', }, ], 'contact': {'email': 'brands@pg.com', 'name': 'P&G Brand Team'}, @@ -506,7 +598,7 @@ class BrandDiscovery( 'version': '1.0', }, { - '$schema': '/schemas/3.0.0-beta.3/brand.json', + '$schema': '/schemas/latest/brand.json', 'authorized_operators': [ { 'brands': ['nike', 'air_jordan'], @@ -523,12 +615,18 @@ class BrandDiscovery( 'keller_type': 'master', 'logos': [ { - 'tags': ['dark', 'icon'], + 'background': 'dark-bg', + 'orientation': 'horizontal', 'url': 'https://cdn.nike.com/swoosh-dark.svg', + 'usage': 'Swoosh icon for dark backgrounds', + 'variant': 'icon', }, { - 'tags': ['full', 'horizontal'], + 'background': 'light-bg', + 'orientation': 'horizontal', 'url': 'https://cdn.nike.com/logo-full.svg', + 'usage': 'Full logo with wordmark for light backgrounds', + 'variant': 'full-lockup', }, ], 'names': [{'en': 'Nike'}, {'zh': '耐克'}, {'ja': 'ナイキ'}], @@ -543,6 +641,7 @@ class BrandDiscovery( ], 'tagline': 'Just Do It', 'tone': 'inspirational, bold, athletic', + 'url': 'https://nike.com', }, { 'brand_agent': {'id': 'nike_dam', 'url': 'https://dam.nike.com/mcp'}, @@ -550,7 +649,12 @@ class BrandDiscovery( 'id': 'air_jordan', 'keller_type': 'endorsed', 'logos': [ - {'tags': ['icon'], 'url': 'https://cdn.nike.com/jumpman.svg'} + { + 'background': 'transparent-bg', + 'orientation': 'square', + 'url': 'https://cdn.nike.com/jumpman.svg', + 'variant': 'icon', + } ], 'names': [{'en': 'Air Jordan'}, {'en': 'Jordan'}, {'en': 'Jumpman'}], 'parent_brand': 'nike', @@ -558,17 +662,23 @@ class BrandDiscovery( {'identifier': 'jordan.com', 'primary': True, 'type': 'website'}, {'identifier': 'jumpman23.com', 'type': 'website'}, ], + 'url': 'https://jordan.com', }, { 'id': 'converse', 'keller_type': 'independent', 'logos': [ - {'tags': ['icon'], 'url': 'https://cdn.converse.com/star.svg'} + { + 'orientation': 'square', + 'url': 'https://cdn.converse.com/star.svg', + 'variant': 'icon', + } ], 'names': [{'en': 'Converse'}], 'properties': [ {'identifier': 'converse.com', 'primary': True, 'type': 'website'} ], + 'url': 'https://converse.com', }, ], 'house': { diff --git a/src/adcp/types/generated_poc/content_standards/artifact.py b/src/adcp/types/generated_poc/content_standards/artifact.py index da36ca2c..83af9aee 100644 --- a/src/adcp/types/generated_poc/content_standards/artifact.py +++ b/src/adcp/types/generated_poc/content_standards/artifact.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: content_standards/artifact.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -15,7 +15,7 @@ class Role(Enum): - title_ = 'title' + title = 'title' paragraph = 'paragraph' heading = 'heading' caption = 'caption' diff --git a/src/adcp/types/generated_poc/core/brand_manifest.py b/src/adcp/types/generated_poc/core/brand_manifest.py deleted file mode 100644 index fc4c225b..00000000 --- a/src/adcp/types/generated_poc/core/brand_manifest.py +++ /dev/null @@ -1,412 +0,0 @@ -# generated by datamodel-codegen: -# filename: core/brand_manifest.json -# timestamp: 2026-02-12T02:11:19+00:00 - -from __future__ import annotations - -from enum import Enum -from typing import Annotated, Any, Literal - -from adcp.types.base import AdCPBaseModel -from pydantic import AnyUrl, AwareDatetime, ConfigDict, EmailStr, Field, RootModel - -from ..enums import asset_content_type - - -class Asset(AdCPBaseModel): - model_config = ConfigDict( - extra='allow', - ) - asset_id: Annotated[str, Field(description='Unique identifier for this asset')] - asset_type: Annotated[ - asset_content_type.AssetContentType, - Field( - description='Type of asset. Note: Brand manifests typically contain basic media assets (image, video, audio, text). Code assets (html, javascript, css) and ad markup (vast, daast) are usually not part of brand asset libraries.' - ), - ] - description: Annotated[str | None, Field(description='Asset description or usage notes')] = None - duration_seconds: Annotated[ - float | None, Field(description='Video/audio duration in seconds') - ] = None - file_size_bytes: Annotated[int | None, Field(description='File size in bytes')] = None - format: Annotated[str | None, Field(description="File format (e.g., 'jpg', 'mp4', 'mp3')")] = ( - None - ) - height: Annotated[int | None, Field(description='Image/video height in pixels')] = None - metadata: Annotated[ - dict[str, Any] | None, Field(description='Additional asset-specific metadata') - ] = None - name: Annotated[str | None, Field(description='Human-readable asset name')] = None - tags: Annotated[ - list[str] | None, - Field( - description="Tags for asset discovery (e.g., 'holiday', 'lifestyle', 'product_shot')" - ), - ] = None - url: Annotated[AnyUrl, Field(description='URL to CDN-hosted asset file')] - width: Annotated[int | None, Field(description='Image/video width in pixels')] = None - - -class Avatar(AdCPBaseModel): - avatar_id: Annotated[str | None, Field(description='Provider-specific avatar identifier')] = ( - None - ) - provider: Annotated[ - str | None, Field(description="Avatar provider (e.g., 'd-id', 'heygen', 'synthesia')") - ] = None - settings: Annotated[ - dict[str, Any] | None, Field(description='Provider-specific avatar settings') - ] = None - - -class Accent(RootModel[str]): - root: Annotated[str, Field(description='Accent color(s)', pattern='^#[0-9A-Fa-f]{6}$')] - - -class Accent1Item(RootModel[str]): - root: Annotated[str, Field(pattern='^#[0-9A-Fa-f]{6}$')] - - -class Accent1(RootModel[list[Accent1Item]]): - root: Annotated[list[Accent1Item], Field(description='Accent color(s)', min_length=1)] - - -class Background(RootModel[str]): - root: Annotated[str, Field(description='Background color(s)', pattern='^#[0-9A-Fa-f]{6}$')] - - -class Background1Item(Accent1Item): - pass - - -class Background1(RootModel[list[Background1Item]]): - root: Annotated[list[Background1Item], Field(description='Background color(s)', min_length=1)] - - -class Primary(RootModel[str]): - root: Annotated[str, Field(description='Primary brand color(s)', pattern='^#[0-9A-Fa-f]{6}$')] - - -class Primary1Item(Accent1Item): - pass - - -class Primary1(RootModel[list[Primary1Item]]): - root: Annotated[list[Primary1Item], Field(description='Primary brand color(s)', min_length=1)] - - -class Secondary(RootModel[str]): - root: Annotated[str, Field(description='Secondary brand color(s)', pattern='^#[0-9A-Fa-f]{6}$')] - - -class Secondary1Item(Accent1Item): - pass - - -class Secondary1(RootModel[list[Secondary1Item]]): - root: Annotated[ - list[Secondary1Item], Field(description='Secondary brand color(s)', min_length=1) - ] - - -class Text(RootModel[str]): - root: Annotated[str, Field(description='Text color(s)', pattern='^#[0-9A-Fa-f]{6}$')] - - -class Text1Item(Accent1Item): - pass - - -class Text1(RootModel[list[Text1Item]]): - root: Annotated[list[Text1Item], Field(description='Text color(s)', min_length=1)] - - -class Colors(AdCPBaseModel): - accent: Annotated[Accent | Accent1 | None, Field(description='Accent color(s)')] = None - background: Annotated[ - Background | Background1 | None, Field(description='Background color(s)') - ] = None - primary: Annotated[Primary | Primary1 | None, Field(description='Primary brand color(s)')] = ( - None - ) - secondary: Annotated[ - Secondary | Secondary1 | None, Field(description='Secondary brand color(s)') - ] = None - text: Annotated[Text | Text1 | None, Field(description='Text color(s)')] = None - - -class Contact(AdCPBaseModel): - email: Annotated[EmailStr | None, Field(description='Contact email')] = None - phone: Annotated[str | None, Field(description='Contact phone number')] = None - - -class Disclaimer(AdCPBaseModel): - context: Annotated[ - str | None, - Field( - description="When this disclaimer applies (e.g., 'financial_products', 'health_claims', 'all')" - ), - ] = None - required: Annotated[bool | None, Field(description='Whether this disclaimer must appear')] = ( - True - ) - text: Annotated[str, Field(description='Disclaimer text')] - - -class Fonts(AdCPBaseModel): - font_urls: Annotated[ - list[AnyUrl] | None, Field(description='URLs to web font files if using custom fonts') - ] = None - primary: Annotated[str | None, Field(description='Primary font family name')] = None - secondary: Annotated[str | None, Field(description='Secondary font family name')] = None - - -class Background2(Enum): - dark_bg = 'dark-bg' - light_bg = 'light-bg' - transparent_bg = 'transparent-bg' - - -class Orientation(Enum): - square = 'square' - horizontal = 'horizontal' - vertical = 'vertical' - stacked = 'stacked' - - -class Variant(Enum): - primary = 'primary' - secondary = 'secondary' - icon = 'icon' - wordmark = 'wordmark' - full_lockup = 'full-lockup' - - -class Logo(AdCPBaseModel): - background: Annotated[ - Background2 | None, - Field( - description='Background compatibility. dark-bg: use on dark backgrounds, light-bg: use on light backgrounds, transparent-bg: has transparent background' - ), - ] = None - height: Annotated[int | None, Field(description='Logo height in pixels')] = None - orientation: Annotated[ - Orientation | None, - Field( - description='Logo aspect ratio orientation. square: ~1:1, horizontal: wide, vertical: tall, stacked: vertically arranged elements' - ), - ] = None - tags: Annotated[ - list[str] | None, - Field( - description='Additional semantic tags for custom categorization beyond the standard orientation, background, and variant fields.' - ), - ] = None - url: Annotated[AnyUrl, Field(description='URL to the logo asset')] - usage: Annotated[ - str | None, - Field( - description="Human-readable description of when to use this logo variant (e.g., 'Primary logo for use on light backgrounds', 'Icon-only variant for small formats')" - ), - ] = None - variant: Annotated[ - Variant | None, - Field( - description='Logo variant type. primary: main logo, secondary: alternative, icon: symbol only, wordmark: text only, full-lockup: complete logo' - ), - ] = None - width: Annotated[int | None, Field(description='Logo width in pixels')] = None - - -class Metadata(AdCPBaseModel): - created_date: Annotated[ - AwareDatetime | None, Field(description='When this brand manifest was created') - ] = None - updated_date: Annotated[ - AwareDatetime | None, Field(description='When this brand manifest was last updated') - ] = None - version: Annotated[str | None, Field(description='Brand card version number')] = None - - -class AgenticCheckout(AdCPBaseModel): - endpoint: Annotated[ - AnyUrl, - Field( - description='Base URL for checkout session API (e.g., https://merchant.com/api/checkout_sessions)' - ), - ] - spec: Annotated[ - Literal['openai_agentic_checkout_v1'], - Field(description='Checkout API specification implemented by the endpoint'), - ] - supported_payment_providers: Annotated[ - list[str] | None, Field(description='Payment providers supported by this checkout endpoint') - ] = None - - -class FeedFormat(Enum): - google_merchant_center = 'google_merchant_center' - facebook_catalog = 'facebook_catalog' - openai_product_feed = 'openai_product_feed' - custom = 'custom' - - -class UpdateFrequency(Enum): - realtime = 'realtime' - hourly = 'hourly' - daily = 'daily' - weekly = 'weekly' - - -class ProductCatalog(AdCPBaseModel): - model_config = ConfigDict( - extra='allow', - ) - agentic_checkout: Annotated[ - AgenticCheckout | None, - Field( - description='Agentic checkout endpoint configuration. Enables AI agents to complete purchases on behalf of users through a structured checkout API.' - ), - ] = None - categories: Annotated[ - list[str] | None, - Field(description='Product categories available in the catalog (for filtering)'), - ] = None - feed_format: Annotated[ - FeedFormat | None, - Field( - description="Format of the product feed. Use 'openai_product_feed' for feeds conforming to the OpenAI Commerce Product Feed specification." - ), - ] = FeedFormat.google_merchant_center - feed_url: Annotated[AnyUrl, Field(description='URL to product catalog feed')] - last_updated: Annotated[ - AwareDatetime | None, Field(description='When the product catalog was last updated') - ] = None - update_frequency: Annotated[ - UpdateFrequency | None, Field(description='How frequently the product catalog is updated') - ] = None - - -class Tone(AdCPBaseModel): - attributes: Annotated[ - list[str] | None, - Field( - description='Personality traits that characterize the brand voice', - examples=[['friendly', 'optimistic', 'conversational', 'authentic']], - ), - ] = None - donts: Annotated[ - list[str] | None, - Field( - description='Guardrails to avoid brand violations - what NOT to do', - examples=[ - [ - 'Avoid corporate jargon', - "Don't be overly formal", - "Don't make exaggerated claims", - ] - ], - ), - ] = None - dos: Annotated[ - list[str] | None, - Field( - description='Specific guidance for copy generation - what TO do', - examples=[ - [ - 'Use simple, everyday language', - 'Address the reader directly', - 'Keep sentences short and punchy', - ] - ], - ), - ] = None - voice: Annotated[ - str | None, - Field( - description="High-level voice descriptor (e.g., 'warm and inviting', 'professional and trustworthy')" - ), - ] = None - - -class Voice(AdCPBaseModel): - provider: Annotated[ - str | None, Field(description="TTS provider (e.g., 'elevenlabs', 'openai', 'amazon_polly')") - ] = None - settings: Annotated[ - dict[str, Any] | None, - Field(description='Provider-specific voice settings (speed, pitch, etc.)'), - ] = None - voice_id: Annotated[str | None, Field(description='Provider-specific voice identifier')] = None - - -class BrandManifest(AdCPBaseModel): - model_config = ConfigDict( - extra='allow', - ) - assets: Annotated[ - list[Asset] | None, - Field( - description='Brand asset library with explicit assets and tags. Assets are referenced inline with URLs pointing to CDN-hosted files.' - ), - ] = None - avatar: Annotated[ - Avatar | None, - Field(description='Brand avatar configuration for visual conversational experiences'), - ] = None - colors: Annotated[ - Colors | None, - Field( - description='Brand color palette. Each role accepts a single hex color or an array of hex colors for brands with multiple values per role.' - ), - ] = None - contact: Annotated[Contact | None, Field(description='Brand contact information')] = None - disclaimers: Annotated[ - list[Disclaimer] | None, - Field(description='Legal disclaimers or required text that must appear in creatives'), - ] = None - fonts: Annotated[Fonts | None, Field(description='Brand typography guidelines')] = None - industry: Annotated[ - str | None, - Field( - description="Industry or vertical (e.g., 'retail', 'automotive', 'finance', 'healthcare')" - ), - ] = None - logos: Annotated[ - list[Logo] | None, - Field( - description='Brand logo assets with structured fields for orientation, background compatibility, and variant type. Use the orientation, background, and variant enum fields for reliable filtering by creative agents.' - ), - ] = None - metadata: Annotated[Metadata | None, Field(description='Additional brand metadata')] = None - name: Annotated[str, Field(description='Brand or business name')] - privacy_policy_url: Annotated[ - AnyUrl | None, - Field( - description="URL to the brand's privacy policy. Used for consumer consent flows when personal data may be shared with the advertiser. AI platforms can use this to present explicit privacy choices to users before data handoff." - ), - ] = None - product_catalog: Annotated[ - ProductCatalog | None, - Field( - description='Product catalog information for e-commerce advertisers. Enables SKU-level creative generation and product selection.' - ), - ] = None - tagline: Annotated[str | None, Field(description='Brand tagline or slogan')] = None - target_audience: Annotated[ - str | None, Field(description='Primary target audience description') - ] = None - tone: Annotated[ - str | Tone | None, - Field(description='Brand voice and messaging tone guidelines for creative agents.'), - ] = None - url: Annotated[ - AnyUrl | None, - Field( - description='Primary brand URL for context and asset discovery. Creative agents can infer brand information from this URL.' - ), - ] = None - voice: Annotated[ - Voice | None, - Field(description='Brand voice configuration for audio/conversational experiences'), - ] = None diff --git a/src/adcp/types/generated_poc/core/brand_manifest_ref.py b/src/adcp/types/generated_poc/core/brand_manifest_ref.py deleted file mode 100644 index 62e1a66a..00000000 --- a/src/adcp/types/generated_poc/core/brand_manifest_ref.py +++ /dev/null @@ -1,35 +0,0 @@ -# generated by datamodel-codegen: -# filename: core/brand_manifest_ref.json -# timestamp: 2026-02-12T02:11:19+00:00 - -from __future__ import annotations - -from typing import Annotated - -from pydantic import AnyUrl, Field, RootModel - -from . import brand_manifest - - -class BrandManifestReference(RootModel[brand_manifest.BrandManifest | AnyUrl]): - root: Annotated[ - brand_manifest.BrandManifest | AnyUrl, - Field( - description='Brand manifest provided either as an inline object or a URL string pointing to a hosted manifest', - examples=[ - { - 'data': { - 'colors': {'primary': '#FF6B35'}, - 'name': 'ACME Corporation', - 'url': 'https://acmecorp.com', - }, - 'description': 'Inline brand manifest', - }, - { - 'data': 'https://cdn.acmecorp.com/brand-manifest.json', - 'description': 'URL string reference to hosted manifest', - }, - ], - title='Brand Manifest Reference', - ), - ] diff --git a/src/adcp/types/generated_poc/core/brand_ref.py b/src/adcp/types/generated_poc/core/brand_ref.py index 6e9d8fd7..1375fd6c 100644 --- a/src/adcp/types/generated_poc/core/brand_ref.py +++ b/src/adcp/types/generated_poc/core/brand_ref.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/brand_ref.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -17,12 +17,15 @@ class BrandReference(AdCPBaseModel): extra='forbid', ) brand_id: Annotated[ - brand_id_1.BrandId, Field(description='Brand identifier within the house portfolio') - ] - house: Annotated[ + brand_id_1.BrandId | None, + Field( + description='Brand identifier within the house portfolio. Optional for single-brand domains.' + ), + ] = None + domain: Annotated[ str, Field( - description="Domain where the house's brand.json is hosted (e.g., 'pg.com', 'nikeinc.com')", + 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])?)*$', ), ] diff --git a/src/adcp/types/generated_poc/core/creative_asset.py b/src/adcp/types/generated_poc/core/creative_asset.py index 86ff91b5..07436150 100644 --- a/src/adcp/types/generated_poc/core/creative_asset.py +++ b/src/adcp/types/generated_poc/core/creative_asset.py @@ -1,13 +1,13 @@ # generated by datamodel-codegen: # filename: core/creative_asset.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations from typing import Annotated from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field +from pydantic import ConfigDict, Field, StringConstraints from ..enums import creative_status from . import format_id as format_id_1 @@ -46,7 +46,7 @@ class CreativeAsset(AdCPBaseModel): ) assets: Annotated[ dict[ - str, + Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9_-]+$')], image_asset.ImageAsset | video_asset.VideoAsset | audio_asset.AudioAsset diff --git a/src/adcp/types/generated_poc/core/creative_brief.py b/src/adcp/types/generated_poc/core/creative_brief.py new file mode 100644 index 00000000..9d2c7e67 --- /dev/null +++ b/src/adcp/types/generated_poc/core/creative_brief.py @@ -0,0 +1,68 @@ +# generated by datamodel-codegen: +# filename: core/creative_brief.json +# timestamp: 2026-02-18T17:56:28+00:00 + +from __future__ import annotations + +from enum import Enum +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from . import reference_asset + + +class Messaging(AdCPBaseModel): + model_config = ConfigDict( + extra='allow', + ) + cta: Annotated[str | None, Field(description='Call-to-action text')] = None + headline: Annotated[str | None, Field(description='Primary headline')] = None + key_messages: Annotated[ + list[str] | None, Field(description='Key messages to communicate in priority order') + ] = None + tagline: Annotated[str | None, Field(description='Supporting tagline or sub-headline')] = None + + +class Objective(Enum): + awareness = 'awareness' + consideration = 'consideration' + conversion = 'conversion' + retention = 'retention' + engagement = 'engagement' + + +class CreativeBrief(AdCPBaseModel): + model_config = ConfigDict( + extra='allow', + ) + audience: Annotated[ + str | None, Field(description='Target audience description for this campaign') + ] = None + messaging: Annotated[ + Messaging | None, Field(description='Messaging framework for the campaign') + ] = None + name: Annotated[str, Field(description='Campaign or flight name for identification')] + objective: Annotated[ + Objective | None, + Field( + description='Campaign objective that guides creative tone and call-to-action strategy' + ), + ] = None + reference_assets: Annotated[ + list[reference_asset.ReferenceAsset] | None, + Field( + description='Visual and strategic reference materials such as mood boards, product shots, example creatives, and strategy documents' + ), + ] = None + territory: Annotated[ + str | None, + Field(description='Creative territory or positioning the campaign should occupy'), + ] = None + tone: Annotated[ + str | None, + Field( + description="Desired tone for this campaign, modulating the brand's base tone (e.g., 'playful and festive', 'premium and aspirational')" + ), + ] = None diff --git a/src/adcp/types/generated_poc/core/creative_brief_ref.py b/src/adcp/types/generated_poc/core/creative_brief_ref.py new file mode 100644 index 00000000..1add5ea0 --- /dev/null +++ b/src/adcp/types/generated_poc/core/creative_brief_ref.py @@ -0,0 +1,39 @@ +# generated by datamodel-codegen: +# filename: core/creative_brief_ref.json +# timestamp: 2026-02-18T17:56:28+00:00 + +from __future__ import annotations + +from typing import Annotated + +from pydantic import AnyUrl, Field, RootModel + +from . import creative_brief + + +class CreativeBriefReference(RootModel[creative_brief.CreativeBrief | AnyUrl]): + root: Annotated[ + creative_brief.CreativeBrief | AnyUrl, + Field( + description='Creative brief provided either as an inline object or a URL string pointing to a hosted brief', + examples=[ + { + 'data': { + 'audience': 'Gift shoppers aged 25-55', + 'messaging': { + 'cta': 'Shop Holiday Deals', + 'headline': 'Give the Gift of Style', + }, + 'name': 'Holiday Campaign 2025', + 'objective': 'conversion', + }, + 'description': 'Inline creative brief', + }, + { + 'data': 'https://cdn.example.com/briefs/holiday-2025.json', + 'description': 'URL string reference to hosted brief', + }, + ], + title='Creative Brief Reference', + ), + ] diff --git a/src/adcp/types/generated_poc/core/creative_manifest.py b/src/adcp/types/generated_poc/core/creative_manifest.py index 5b37aa20..8fe19f9b 100644 --- a/src/adcp/types/generated_poc/core/creative_manifest.py +++ b/src/adcp/types/generated_poc/core/creative_manifest.py @@ -1,13 +1,13 @@ # generated by datamodel-codegen: # filename: core/creative_manifest.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations from typing import Annotated from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field +from pydantic import ConfigDict, Field, StringConstraints from . import ext as ext_1 from . import format_id as format_id_1 @@ -33,7 +33,7 @@ class CreativeManifest(AdCPBaseModel): ) assets: Annotated[ dict[ - str, + Annotated[str, StringConstraints(pattern=r'^[a-z0-9_]+$')], image_asset.ImageAsset | video_asset.VideoAsset | audio_asset.AudioAsset diff --git a/src/adcp/types/generated_poc/core/creative_variant.py b/src/adcp/types/generated_poc/core/creative_variant.py index c1770a34..324298cb 100644 --- a/src/adcp/types/generated_poc/core/creative_variant.py +++ b/src/adcp/types/generated_poc/core/creative_variant.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/creative_variant.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -54,7 +54,7 @@ class CreativeVariant(DeliveryMetrics): manifest: Annotated[ creative_manifest.CreativeManifest | None, Field( - description='The rendered creative manifest for this variant — 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 manifest. Pass to preview_creative to re-render.' + description='The rendered creative manifest for this variant — 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.' ), ] = None variant_id: Annotated[str, Field(description='Platform-assigned identifier for this variant')] diff --git a/src/adcp/types/generated_poc/core/format.py b/src/adcp/types/generated_poc/core/format.py index 3a28530b..0c65bdc3 100644 --- a/src/adcp/types/generated_poc/core/format.py +++ b/src/adcp/types/generated_poc/core/format.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/format.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -221,14 +221,6 @@ class Assets13(BaseIndividualAsset): requirements: daast_asset_requirements.DaastAssetRequirements | None = None -class Assets14(BaseIndividualAsset): - asset_type: Literal['promoted_offerings'] = 'promoted_offerings' - item_type: Literal['individual'] = 'individual' - requirements: ( - promoted_offerings_asset_requirements.PromotedOfferingsAssetRequirements | None - ) = None - - class Assets15(BaseIndividualAsset): asset_type: Literal['url'] = 'url' item_type: Literal['individual'] = 'individual' @@ -291,13 +283,6 @@ class Assets27(BaseGroupAsset): requirements: daast_asset_requirements.DaastAssetRequirements | None = None -class Assets28(BaseGroupAsset): - asset_type: Literal['promoted_offerings'] = 'promoted_offerings' - requirements: ( - promoted_offerings_asset_requirements.PromotedOfferingsAssetRequirements | None - ) = None - - class Assets29(BaseGroupAsset): asset_type: Literal['url'] = 'url' requirements: url_asset_requirements.UrlAssetRequirements | None = None @@ -308,6 +293,55 @@ class Assets30(BaseGroupAsset): requirements: webhook_asset_requirements.WebhookAssetRequirements | None = None +class FormatCard(AdCPBaseModel): + model_config = ConfigDict( + extra='allow', + ) + format_id: Annotated[ + format_id_1.FormatId, + Field( + description='Creative format defining the card layout (typically format_card_standard)' + ), + ] + manifest: Annotated[ + dict[str, Any], + Field(description='Asset manifest for rendering the card, structure defined by the format'), + ] + + +class FormatCardDetailed(AdCPBaseModel): + model_config = ConfigDict( + extra='allow', + ) + format_id: Annotated[ + format_id_1.FormatId, + Field( + description='Creative format defining the detailed card layout (typically format_card_detailed)' + ), + ] + manifest: Annotated[ + dict[str, Any], + Field( + description='Asset manifest for rendering the detailed card, structure defined by the format' + ), + ] + + +class Assets14(BaseIndividualAsset): + asset_type: Literal['promoted_offerings'] = 'promoted_offerings' + item_type: Literal['individual'] = 'individual' + requirements: ( + promoted_offerings_asset_requirements.PromotedOfferingsAssetRequirements | None + ) = None + + +class Assets28(BaseGroupAsset): + asset_type: Literal['promoted_offerings'] = 'promoted_offerings' + requirements: ( + promoted_offerings_asset_requirements.PromotedOfferingsAssetRequirements | None + ) = None + + class Assets17(AdCPBaseModel): asset_group_id: Annotated[ str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')") @@ -356,40 +390,6 @@ class Assets17(AdCPBaseModel): ] = SelectionMode.sequential -class FormatCard(AdCPBaseModel): - model_config = ConfigDict( - extra='allow', - ) - format_id: Annotated[ - format_id_1.FormatId, - Field( - description='Creative format defining the card layout (typically format_card_standard)' - ), - ] - manifest: Annotated[ - dict[str, Any], - Field(description='Asset manifest for rendering the card, structure defined by the format'), - ] - - -class FormatCardDetailed(AdCPBaseModel): - model_config = ConfigDict( - extra='allow', - ) - format_id: Annotated[ - format_id_1.FormatId, - Field( - description='Creative format defining the detailed card layout (typically format_card_detailed)' - ), - ] - manifest: Annotated[ - dict[str, Any], - Field( - description='Asset manifest for rendering the detailed card, structure defined by the format' - ), - ] - - class Format(AdCPBaseModel): model_config = ConfigDict( extra='allow', @@ -464,7 +464,7 @@ class Format(AdCPBaseModel): output_format_ids: Annotated[ list[format_id_1.FormatId] | None, Field( - description='For generative formats: array of format IDs that this format can generate. When a format accepts inputs like brand_manifest and message, this specifies what concrete output formats can be produced (e.g., a generative banner format might output standard image banner formats).' + description='For generative formats: array of format IDs that this format can generate. When a format accepts inputs like brand context and message, this specifies what concrete output formats can be produced (e.g., a generative banner format might output standard image banner formats).' ), ] = None renders: Annotated[ diff --git a/src/adcp/types/generated_poc/core/product.py b/src/adcp/types/generated_poc/core/product.py index 4d498517..211b3d30 100644 --- a/src/adcp/types/generated_poc/core/product.py +++ b/src/adcp/types/generated_poc/core/product.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/product.json -# timestamp: 2026-02-12T10:29:35+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -14,7 +14,7 @@ from ..enums import channels as channels_1 from ..enums import delivery_type as delivery_type_1 from . import creative_policy as creative_policy_1 -from . import data_provider_signal_selector +from . import data_provider_signal_selector, delivery_forecast from . import ext as ext_1 from . import format_id as format_id_1 from . import measurement as measurement_1 @@ -138,7 +138,7 @@ class Product(AdCPBaseModel): catalog_match: Annotated[ CatalogMatch | None, Field( - description="When the buyer provides a brand_manifest with product_catalog, indicates which of the buyer's catalog items are eligible for this product. Enables buyers to make informed product_selector choices in create_media_buy. Only present for products where catalog matching is relevant (e.g. sponsored product listings on retail media). Sellers SHOULD include at least one of matched_gtins or matched_skus." + description="When the buyer provides a brand with product_catalog, indicates which of the buyer's catalog items are eligible for this product. Enables buyers to make informed product_selector choices in create_media_buy. Only present for products where catalog matching is relevant (e.g. sponsored product listings on retail media). Sellers SHOULD include at least one of matched_gtins or matched_skus." ), ] = None channels: Annotated[ @@ -170,14 +170,16 @@ class Product(AdCPBaseModel): description: Annotated[ str, Field(description='Detailed description of the product and its inventory') ] - estimated_exposures: Annotated[ - int | None, - Field(description='Estimated exposures/impressions for guaranteed products', ge=0), - ] = None expires_at: Annotated[ AwareDatetime | None, Field(description='Expiration timestamp for custom products') ] = None ext: ext_1.ExtensionObject | None = None + forecast: Annotated[ + delivery_forecast.DeliveryForecast | None, + Field( + description='Forecasted delivery metrics for this product. Gives buyers an estimate of expected performance before requesting a proposal.' + ), + ] = None format_ids: Annotated[ list[format_id_1.FormatId], Field( diff --git a/src/adcp/types/generated_poc/core/promoted_offerings.py b/src/adcp/types/generated_poc/core/promoted_offerings.py index 09c3c7ae..bf34c2c3 100644 --- a/src/adcp/types/generated_poc/core/promoted_offerings.py +++ b/src/adcp/types/generated_poc/core/promoted_offerings.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/promoted_offerings.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -10,7 +10,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, ConfigDict, Field -from . import brand_manifest_ref, offering, promoted_products +from . import brand_ref, offering, promoted_products class AssetType(Enum): @@ -49,12 +49,12 @@ class PromotedOfferings(AdCPBaseModel): ) asset_selectors: Annotated[ AssetSelectors | None, - Field(description='Selectors to choose specific assets from the brand manifest'), + Field(description="Selectors to choose specific assets from the brand's asset library"), ] = None - brand_manifest: Annotated[ - brand_manifest_ref.BrandManifestReference, + brand: Annotated[ + brand_ref.BrandReference, Field( - description='Brand information manifest containing assets, themes, and guidelines. Can be provided inline or as a URL reference to a hosted manifest.' + description='Brand reference. Resolved to full brand identity (logos, colors, tone, assets) at execution time for creative generation.' ), ] offerings: Annotated[ @@ -66,7 +66,7 @@ class PromotedOfferings(AdCPBaseModel): product_selectors: Annotated[ promoted_products.PromotedProducts | None, Field( - description='Selectors to choose which products/offerings from the brand manifest product catalog to promote' + description="Selectors to choose which products/offerings from the brand's product catalog to promote" ), ] = None si_agent_url: Annotated[ diff --git a/src/adcp/types/generated_poc/core/promoted_products.py b/src/adcp/types/generated_poc/core/promoted_products.py index 6025773f..bc808f6b 100644 --- a/src/adcp/types/generated_poc/core/promoted_products.py +++ b/src/adcp/types/generated_poc/core/promoted_products.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/promoted_products.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -21,7 +21,7 @@ class PromotedProducts(AdCPBaseModel): manifest_category: Annotated[ str | None, Field( - description="Select products from a specific category in the brand manifest product catalog (e.g., 'beverages/soft-drinks', 'food/sauces')" + description="Select products from a specific category in the brand's product catalog (e.g., 'beverages/soft-drinks', 'food/sauces')" ), ] = None manifest_gtins: Annotated[ @@ -33,16 +33,16 @@ class PromotedProducts(AdCPBaseModel): manifest_query: Annotated[ str | None, Field( - description="Natural language query to select products from the brand manifest (e.g., 'all Kraft Heinz pasta sauces', 'organic products under $20')" + description="Natural language query to select products from the brand's catalog (e.g., 'all pasta sauces', 'organic products under $20')" ), ] = None manifest_skus: Annotated[ list[str] | None, - Field(description='Direct product SKU references from the brand manifest product catalog'), + Field(description="Direct product SKU references from the brand's product catalog"), ] = None manifest_tags: Annotated[ list[str] | None, Field( - description="Select products by tags from the brand manifest product catalog (e.g., 'organic', 'sauces', 'holiday')" + description="Select products by tags from the brand's product catalog (e.g., 'organic', 'sauces', 'holiday')" ), ] = None diff --git a/src/adcp/types/generated_poc/core/proposal.py b/src/adcp/types/generated_poc/core/proposal.py index ab762369..08e67d72 100644 --- a/src/adcp/types/generated_poc/core/proposal.py +++ b/src/adcp/types/generated_poc/core/proposal.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/proposal.json -# timestamp: 2026-02-12T12:00:44+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -63,7 +63,7 @@ class Proposal(AdCPBaseModel): proposal_id: Annotated[ str, Field( - description='Unique identifier for this proposal. Used to refine the proposal in subsequent get_products calls or to execute it via create_media_buy.' + description='Unique identifier for this proposal. Used to execute it via create_media_buy.' ), ] total_budget_guidance: Annotated[ diff --git a/src/adcp/types/generated_poc/core/reference_asset.py b/src/adcp/types/generated_poc/core/reference_asset.py new file mode 100644 index 00000000..37cd8651 --- /dev/null +++ b/src/adcp/types/generated_poc/core/reference_asset.py @@ -0,0 +1,41 @@ +# generated by datamodel-codegen: +# filename: core/reference_asset.json +# timestamp: 2026-02-18T17:56:28+00:00 + +from __future__ import annotations + +from enum import Enum +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import AnyUrl, ConfigDict, Field + + +class Role(Enum): + style_reference = 'style_reference' + product_shot = 'product_shot' + mood_board = 'mood_board' + example_creative = 'example_creative' + logo = 'logo' + strategy_doc = 'strategy_doc' + + +class ReferenceAsset(AdCPBaseModel): + model_config = ConfigDict( + extra='allow', + ) + description: Annotated[ + str | None, + Field( + description='Human-readable description of the asset and how it should inform creative generation' + ), + ] = None + role: Annotated[ + Role, + Field( + description='How the creative agent should use this asset. style_reference: match the visual style; product_shot: include this product; mood_board: overall look and feel; example_creative: example of a similar execution; logo: logo to use; strategy_doc: strategy or planning document for context' + ), + ] + url: Annotated[ + AnyUrl, Field(description='URL to the reference asset (image, video, or document)') + ] diff --git a/src/adcp/types/generated_poc/core/requirements/promoted_offerings_asset_requirements.py b/src/adcp/types/generated_poc/core/requirements/promoted_offerings_asset_requirements.py index 72cfa053..339f71b6 100644 --- a/src/adcp/types/generated_poc/core/requirements/promoted_offerings_asset_requirements.py +++ b/src/adcp/types/generated_poc/core/requirements/promoted_offerings_asset_requirements.py @@ -1,14 +1,25 @@ # generated by datamodel-codegen: # filename: core/requirements/promoted_offerings_asset_requirements.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations +from typing import Annotated + from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict +from pydantic import ConfigDict, Field + +from ...enums import promoted_offerings_requirement class PromotedOfferingsAssetRequirements(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) + requires: Annotated[ + list[promoted_offerings_requirement.PromotedOfferingsRequirement] | None, + Field( + description="Content that must be available in this format's promoted offerings. Each value is a presence check: the referenced field must exist and be non-empty. For brand.* paths, the validating agent resolves the brand reference first.", + min_length=1, + ), + ] = None diff --git a/src/adcp/types/generated_poc/enums/promoted_offerings_requirement.py b/src/adcp/types/generated_poc/enums/promoted_offerings_requirement.py new file mode 100644 index 00000000..de9e8d67 --- /dev/null +++ b/src/adcp/types/generated_poc/enums/promoted_offerings_requirement.py @@ -0,0 +1,17 @@ +# generated by datamodel-codegen: +# filename: enums/promoted_offerings_requirement.json +# timestamp: 2026-02-18T17:56:28+00:00 + +from __future__ import annotations + +from enum import Enum + + +class PromotedOfferingsRequirement(Enum): + si_agent_url = 'si_agent_url' + offerings = 'offerings' + brand_logos = 'brand.logos' + brand_colors = 'brand.colors' + brand_tone = 'brand.tone' + brand_assets = 'brand.assets' + brand_product_catalog = 'brand.product_catalog' diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_request.py b/src/adcp/types/generated_poc/media_buy/build_creative_request.py index 745dd31d..03faa56c 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_request.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/build_creative_request.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -9,7 +9,9 @@ from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field +from ..core import brand_ref from ..core import context as context_1 +from ..core import creative_brief_ref from ..core import creative_manifest as creative_manifest_1 from ..core import ext as ext_1 from ..core import format_id @@ -19,7 +21,19 @@ class BuildCreativeRequest(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) + brand: Annotated[ + brand_ref.BrandReference | None, + Field( + description='Brand reference for creative generation. Resolved to full brand identity (colors, logos, tone) at execution time.' + ), + ] = None context: context_1.ContextObject | None = None + creative_brief: Annotated[ + creative_brief_ref.CreativeBriefReference | None, + Field( + description='Campaign-level creative brief with objective, audience, messaging, and reference assets. Can be an inline brief object or a URL to a hosted brief. Supplements the natural language message with structured creative direction.' + ), + ] = None creative_manifest: Annotated[ creative_manifest_1.CreativeManifest | None, Field( diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py index 48b1eb70..83237f71 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/create_media_buy_request.json -# timestamp: 2026-02-12T12:00:44+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -10,7 +10,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, AwareDatetime, ConfigDict, Field -from ..core import brand_manifest_ref +from ..core import brand_ref from ..core import context as context_1 from ..core import ext as ext_1 from ..core import reporting_webhook as reporting_webhook_1 @@ -112,10 +112,10 @@ class CreateMediaBuyRequest(AdCPBaseModel): description='Optional webhook configuration for content artifact delivery. Used by governance agents to validate content adjacency. Seller pushes artifacts to this endpoint; orchestrator forwards to governance agent for validation.' ), ] = None - brand_manifest: Annotated[ - brand_manifest_ref.BrandManifestReference, + brand: Annotated[ + brand_ref.BrandReference, Field( - description='Brand information manifest serving as the namespace and identity for this media buy. Provides brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest. Can be cached and reused across multiple requests.' + description='Brand reference for this media buy. Resolved to full brand identity at execution time from brand.json or the registry.' ), ] buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for this media buy")] diff --git a/src/adcp/types/generated_poc/media_buy/get_products_request.py b/src/adcp/types/generated_poc/media_buy/get_products_request.py index cca8a75f..35c42942 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_request.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_request.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -9,7 +9,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field -from ..core import brand_manifest_ref +from ..core import brand_ref from ..core import context as context_1 from ..core import ext as ext_1 from ..core import pagination_request, product_filters, promoted_products, property_list_ref @@ -25,17 +25,14 @@ class GetProductsRequest(AdCPBaseModel): description="Account ID for product lookup. Required when the seller declares account.required_for_products = true in capabilities. Returns products with pricing specific to this account's rate card." ), ] = None - brand_manifest: Annotated[ - brand_manifest_ref.BrandManifestReference | None, + brand: Annotated[ + brand_ref.BrandReference | None, Field( - description='Brand information manifest providing brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest.' + description='Brand reference for product discovery context. Resolved to full brand identity at execution time.' ), ] = None brief: Annotated[ - str | None, - Field( - description="Natural language description of campaign requirements. When refining a proposal, can include instructions like 'focus more on German speakers' or 'increase mobile allocation'." - ), + str | None, Field(description='Natural language description of campaign requirements.') ] = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None @@ -44,7 +41,7 @@ class GetProductsRequest(AdCPBaseModel): product_selectors: Annotated[ promoted_products.PromotedProducts | None, Field( - description='Selectors to filter the brand manifest product catalog for product discovery. When provided, sellers should only return advertising products where the selected catalog items have matches. Uses the same selection methods as promoted-offerings.' + description="Selectors to filter the brand's product catalog for product discovery. When provided, sellers should only return advertising products where the selected catalog items have matches. Uses the same selection methods as promoted-offerings." ), ] = None property_list: Annotated[ @@ -53,9 +50,3 @@ class GetProductsRequest(AdCPBaseModel): description='[AdCP 3.0] Reference to an externally managed property list. When provided, the sales agent should filter products to only those available on properties in the list.' ), ] = None - proposal_id: Annotated[ - str | None, - Field( - description='Optional proposal ID to refine. When provided with a brief, the publisher will use the brief as refinement instructions for the specified proposal and return an updated version.' - ), - ] = None diff --git a/src/adcp/types/generated_poc/media_buy/get_products_response.py b/src/adcp/types/generated_poc/media_buy/get_products_response.py index 81ac607f..e045d40f 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_response.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_response.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -42,6 +42,6 @@ class GetProductsResponse(AdCPBaseModel): proposals: Annotated[ list[proposal.Proposal] | None, Field( - description='Optional array of proposed media plans with budget allocations across products. Publishers include proposals when they can provide strategic guidance based on the brief. Proposals are actionable - buyers can refine them via subsequent get_products calls or execute them directly via create_media_buy.' + description='Optional array of proposed media plans with budget allocations across products. Publishers include proposals when they can provide strategic guidance based on the brief. Proposals are actionable - buyers can refine them via follow-up get_products calls within the same session, or execute them directly via create_media_buy.' ), ] = None diff --git a/src/adcp/types/generated_poc/media_buy/list_creatives_request.py b/src/adcp/types/generated_poc/media_buy/list_creatives_request.py index e38c9205..3d00c12b 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creatives_request.py +++ b/src/adcp/types/generated_poc/media_buy/list_creatives_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/list_creatives_request.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -20,7 +20,7 @@ class FieldModel(Enum): creative_id = 'creative_id' name = 'name' - format_ = 'format' + format = 'format' status = 'status' created_date = 'created_date' updated_date = 'updated_date' diff --git a/src/adcp/types/generated_poc/media_buy/list_creatives_response.py b/src/adcp/types/generated_poc/media_buy/list_creatives_response.py index 45a3e3d4..8b9fd0ba 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creatives_response.py +++ b/src/adcp/types/generated_poc/media_buy/list_creatives_response.py @@ -1,13 +1,13 @@ # generated by datamodel-codegen: # filename: media_buy/list_creatives_response.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations from typing import Annotated from adcp.types.base import AdCPBaseModel -from pydantic import AwareDatetime, ConfigDict, Field +from pydantic import AwareDatetime, ConfigDict, Field, StringConstraints from ..core import account as account_1 from ..core import context as context_1 @@ -125,7 +125,7 @@ class Creative(AdCPBaseModel): ] = None assets: Annotated[ dict[ - str, + Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9_-]+$')], image_asset.ImageAsset | video_asset.VideoAsset | audio_asset.AudioAsset @@ -185,7 +185,8 @@ class ListCreativesResponse(AdCPBaseModel): ] ext: ext_1.ExtensionObject | None = None format_summary: Annotated[ - dict[str, int] | None, Field(description='Breakdown of creatives by format type') + dict[Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9_-]+$')], int] | None, + Field(description='Breakdown of creatives by format type'), ] = None pagination: pagination_response.PaginationResponse query_summary: Annotated[ diff --git a/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py b/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py index 87c67d18..8579eb65 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py +++ b/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py @@ -1,13 +1,13 @@ # generated by datamodel-codegen: # filename: media_buy/sync_creatives_request.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations from typing import Annotated from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field +from pydantic import ConfigDict, Field, StringConstraints from ..core import context as context_1 from ..core import creative_asset @@ -27,7 +27,7 @@ class SyncCreativesRequest(AdCPBaseModel): ), ] = None assignments: Annotated[ - dict[str, list[str]] | None, + dict[Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9_-]+$')], list[str]] | None, Field(description='Optional bulk assignment of creatives to packages'), ] = None context: context_1.ContextObject | None = None diff --git a/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py b/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py index 3359b558..0f10c277 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py +++ b/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py @@ -1,13 +1,13 @@ # generated by datamodel-codegen: # filename: media_buy/sync_creatives_response.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations from typing import Annotated from adcp.types.base import AdCPBaseModel -from pydantic import AnyUrl, AwareDatetime, ConfigDict, Field, RootModel +from pydantic import AnyUrl, AwareDatetime, ConfigDict, Field, RootModel, StringConstraints from ..core import account as account_1 from ..core import context as context_1 @@ -48,7 +48,7 @@ class Creative(AdCPBaseModel): ), ] = None assignment_errors: Annotated[ - dict[str, str] | None, + dict[Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9_-]+$')], str] | None, Field( description='Assignment errors by package ID (only present when assignment failures occurred)' ), diff --git a/src/adcp/types/generated_poc/property/create_property_list_request.py b/src/adcp/types/generated_poc/property/create_property_list_request.py index 3276824a..5ad27b10 100644 --- a/src/adcp/types/generated_poc/property/create_property_list_request.py +++ b/src/adcp/types/generated_poc/property/create_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/create_property_list_request.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -9,7 +9,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import ConfigDict, Field -from ..core import brand_manifest as brand_manifest_1 +from ..core import brand_ref from ..core import context as context_1 from ..core import ext as ext_1 from . import base_property_source, property_list_filters @@ -26,10 +26,10 @@ class CreatePropertyListRequest(AdCPBaseModel): min_length=1, ), ] = None - brand_manifest: Annotated[ - brand_manifest_1.BrandManifest | None, + brand: Annotated[ + brand_ref.BrandReference | None, Field( - description='Brand identity and requirements. When provided, the agent automatically applies appropriate rules based on brand characteristics (industry, target_audience, etc.).' + description='Brand reference. When provided, the agent automatically applies appropriate rules based on brand characteristics (industry, target_audience, etc.). Resolved at execution time.' ), ] = None context: context_1.ContextObject | None = None diff --git a/src/adcp/types/generated_poc/property/property_list.py b/src/adcp/types/generated_poc/property/property_list.py index e9f74400..8c9136ae 100644 --- a/src/adcp/types/generated_poc/property/property_list.py +++ b/src/adcp/types/generated_poc/property/property_list.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/property_list.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -9,7 +9,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, AwareDatetime, ConfigDict, Field -from ..core import brand_manifest as brand_manifest_1 +from ..core import brand_ref from . import base_property_source, property_list_filters @@ -23,9 +23,11 @@ class PropertyList(AdCPBaseModel): description="Array of property sources to evaluate. Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers). If omitted, queries the agent's entire property database." ), ] = None - brand_manifest: Annotated[ - brand_manifest_1.BrandManifest | None, - Field(description='Brand identity used to automatically apply appropriate rules'), + brand: Annotated[ + brand_ref.BrandReference | None, + Field( + description='Brand reference used to automatically apply appropriate rules. Resolved to full brand identity at execution time.' + ), ] = None cache_duration_hours: Annotated[ int | None, diff --git a/src/adcp/types/generated_poc/property/update_property_list_request.py b/src/adcp/types/generated_poc/property/update_property_list_request.py index b71a3350..11f014b5 100644 --- a/src/adcp/types/generated_poc/property/update_property_list_request.py +++ b/src/adcp/types/generated_poc/property/update_property_list_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: property/update_property_list_request.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -9,7 +9,7 @@ from adcp.types.base import AdCPBaseModel from pydantic import AnyUrl, ConfigDict, Field -from ..core import brand_manifest as brand_manifest_1 +from ..core import brand_ref from ..core import context as context_1 from ..core import ext as ext_1 from . import base_property_source, property_list_filters @@ -25,9 +25,11 @@ class UpdatePropertyListRequest(AdCPBaseModel): description='Complete replacement for the base properties list (not a patch). Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers).' ), ] = None - brand_manifest: Annotated[ - brand_manifest_1.BrandManifest | None, - Field(description='Update brand identity and requirements'), + brand: Annotated[ + brand_ref.BrandReference | None, + Field( + description='Update brand reference. Resolved to full brand identity at execution time.' + ), ] = None context: context_1.ContextObject | None = None description: Annotated[str | None, Field(description='New description')] = None diff --git a/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py b/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py index fce653e7..abd765e4 100644 --- a/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py +++ b/src/adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: protocol/get_adcp_capabilities_response.json -# timestamp: 2026-02-12T02:11:19+00:00 +# timestamp: 2026-02-18T17:56:28+00:00 from __future__ import annotations @@ -74,6 +74,18 @@ class Adcp(AdCPBaseModel): ] +class Creative(AdCPBaseModel): + model_config = ConfigDict( + extra='allow', + ) + supports_brief: Annotated[ + bool | None, + Field( + description='Whether this creative agent accepts creative_brief in build_creative requests for structured campaign-level creative direction' + ), + ] = None + + class ExtensionsSupportedItem(RootModel[str]): root: Annotated[ str, @@ -447,8 +459,8 @@ class MediaBuy(AdCPBaseModel): class SponsoredIntelligence(AdCPBaseModel): - brand_manifest_url: Annotated[ - AnyUrl | None, Field(description='URL to brand manifest with colors, fonts, logos, tone') + brand_url: Annotated[ + AnyUrl | None, Field(description='URL to brand.json with colors, fonts, logos, tone') ] = None capabilities: Annotated[ si_capabilities.SiCapabilities, @@ -469,6 +481,12 @@ class GetAdcpCapabilitiesResponse(AdCPBaseModel): ] = None adcp: Annotated[Adcp, Field(description='Core AdCP protocol information')] context: context_1.ContextObject | None = None + creative: Annotated[ + Creative | None, + Field( + description='Creative protocol capabilities. Only present if creative is in supported_protocols.' + ), + ] = None errors: Annotated[ list[error.Error] | None, Field(description='Task-specific errors and warnings') ] = None diff --git a/tests/test_registry.py b/tests/test_registry.py index a865bc9a..926517b5 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -9,7 +9,7 @@ from adcp.exceptions import RegistryError from adcp.registry import DEFAULT_REGISTRY_URL, MAX_BULK_DOMAINS, RegistryClient -from adcp.types.core import ResolvedBrand, ResolvedProperty +from adcp.types.core import Member, ResolvedBrand, ResolvedProperty BRAND_DATA = { "canonical_id": "nike.com", @@ -20,6 +20,15 @@ "brand_manifest": {"name": "Nike"}, } +BRAND_DATA_NEW = { + "canonical_id": "nike.com", + "canonical_domain": "nike.com", + "brand_name": "Nike", + "keller_type": "master", + "source": "brand_json", + "brand": {"name": "Nike"}, +} + PROPERTY_DATA = { "publisher_domain": "nytimes.com", "source": "adagents_json", @@ -28,6 +37,27 @@ "verified": True, } +MEMBER_DATA = { + "id": "d5b4a558-fdff-4b0c-9876-8327b0d09d7f", + "slug": "adgentek", + "display_name": "Adgentek", + "description": "AI-native advertising infrastructure for the agentic web.", + "tagline": None, + "logo_url": "https://example.com/logo.png", + "logo_light_url": None, + "logo_dark_url": None, + "contact_email": "hello@adgentek.ai", + "contact_website": "https://adgentek.ai", + "offerings": ["buyer_agent", "sales_agent", "signals_agent"], + "markets": ["North America", "EMEA"], + "agents": [], + "brands": [], + "is_public": True, + "is_founding_member": True, + "featured": False, + "si_enabled": False, +} + def _mock_response(status_code: int = 200, json_data: object = None) -> MagicMock: resp = MagicMock() @@ -61,7 +91,7 @@ async def test_close_noop_for_external_client(self): external = MagicMock() rc = RegistryClient(client=external) await rc.close() - # external client should not be closed by RegistryClient + external.aclose.assert_not_called() @pytest.mark.asyncio async def test_context_manager(self): @@ -176,6 +206,19 @@ async def test_extra_fields_preserved(self): assert result is not None assert result.extra_field == "extra_value" # type: ignore[attr-defined] + @pytest.mark.asyncio + async def test_resolves_brand_with_new_brand_field(self): + """Registry returns 'brand' field (new API); both brand and brand_manifest accessible.""" + mock_client = MagicMock() + mock_client.get = AsyncMock(return_value=_mock_response(200, BRAND_DATA_NEW)) + + rc = RegistryClient(client=mock_client) + result = await rc.lookup_brand("nike.com") + + assert result is not None + assert result.brand == {"name": "Nike"} + assert result.brand_manifest == {"name": "Nike"} + @pytest.mark.asyncio async def test_raises_on_invalid_response_data(self): mock_client = MagicMock() @@ -241,6 +284,20 @@ async def mock_post(url, json, headers, timeout): assert call_count == 2 # 100 + 50 assert len(results) == 150 + @pytest.mark.asyncio + async def test_domain_absent_from_response_defaults_to_none(self): + """Domain omitted from results dict (not explicitly null) defaults to None.""" + mock_client = MagicMock() + mock_client.post = AsyncMock( + return_value=_mock_response(200, {"results": {"nike.com": BRAND_DATA}}) + ) + + rc = RegistryClient(client=mock_client) + results = await rc.lookup_brands(["nike.com", "other.com"]) + + assert isinstance(results["nike.com"], ResolvedBrand) + assert results["other.com"] is None + @pytest.mark.asyncio async def test_raises_on_server_error(self): mock_client = MagicMock() @@ -251,6 +308,17 @@ async def test_raises_on_server_error(self): await rc.lookup_brands(["nike.com"]) assert exc_info.value.status_code == 500 + @pytest.mark.asyncio + async def test_chunk_failure_propagates(self): + """A failure in one chunk raises RegistryError from lookup_brands.""" + mock_client = MagicMock() + mock_client.post = AsyncMock(return_value=_mock_response(503)) + + rc = RegistryClient(client=mock_client) + with pytest.raises(RegistryError) as exc_info: + await rc.lookup_brands([f"domain-{i}.com" for i in range(150)]) + assert exc_info.value.status_code == 503 + class TestLookupProperty: """Test single property lookup.""" @@ -395,8 +463,170 @@ async def test_raises_on_server_error(self): assert exc_info.value.status_code == 500 +class TestListMembers: + """Test AAO member directory listing.""" + + @pytest.mark.asyncio + async def test_lists_members(self): + mock_client = MagicMock() + mock_client.get = AsyncMock( + return_value=_mock_response(200, {"members": [MEMBER_DATA]}) + ) + + rc = RegistryClient(client=mock_client) + members = await rc.list_members() + + assert len(members) == 1 + assert isinstance(members[0], Member) + assert members[0].slug == "adgentek" + assert members[0].display_name == "Adgentek" + + @pytest.mark.asyncio + async def test_empty_member_list(self): + mock_client = MagicMock() + mock_client.get = AsyncMock( + return_value=_mock_response(200, {"members": []}) + ) + + rc = RegistryClient(client=mock_client) + members = await rc.list_members() + assert members == [] + + @pytest.mark.asyncio + async def test_sends_limit_param(self): + mock_client = MagicMock() + mock_client.get = AsyncMock( + return_value=_mock_response(200, {"members": []}) + ) + + rc = RegistryClient( + base_url="https://test.example.com", + client=mock_client, + user_agent="test-agent", + ) + await rc.list_members(limit=25) + + mock_client.get.assert_called_once_with( + "https://test.example.com/api/members", + params={"limit": 25}, + headers={"User-Agent": "test-agent"}, + timeout=10.0, + ) + + @pytest.mark.asyncio + async def test_raises_on_server_error(self): + mock_client = MagicMock() + mock_client.get = AsyncMock(return_value=_mock_response(500)) + + rc = RegistryClient(client=mock_client) + with pytest.raises(RegistryError) as exc_info: + await rc.list_members() + assert exc_info.value.status_code == 500 + + @pytest.mark.asyncio + async def test_raises_on_timeout(self): + mock_client = MagicMock() + mock_client.get = AsyncMock(side_effect=httpx.ReadTimeout("timeout")) + + rc = RegistryClient(client=mock_client) + with pytest.raises(RegistryError, match="timed out"): + await rc.list_members() + + @pytest.mark.asyncio + async def test_raises_on_invalid_limit(self): + rc = RegistryClient(client=MagicMock()) + with pytest.raises(ValueError, match="limit must be at least 1"): + await rc.list_members(limit=0) + + @pytest.mark.asyncio + async def test_missing_members_key_returns_empty_list(self): + """Malformed 200 response with no 'members' key returns empty list.""" + mock_client = MagicMock() + mock_client.get = AsyncMock(return_value=_mock_response(200, {})) + + rc = RegistryClient(client=mock_client) + members = await rc.list_members() + assert members == [] + + +class TestGetMember: + """Test AAO member lookup by slug.""" + + @pytest.mark.asyncio + async def test_resolves_known_slug(self): + mock_client = MagicMock() + mock_client.get = AsyncMock(return_value=_mock_response(200, MEMBER_DATA)) + + rc = RegistryClient(client=mock_client) + member = await rc.get_member("adgentek") + + assert member is not None + assert isinstance(member, Member) + assert member.slug == "adgentek" + assert member.contact_email == "hello@adgentek.ai" + assert "buyer_agent" in member.offerings + assert member.is_founding_member is True + + @pytest.mark.asyncio + async def test_returns_none_for_404(self): + mock_client = MagicMock() + mock_client.get = AsyncMock(return_value=_mock_response(404)) + + rc = RegistryClient(client=mock_client) + member = await rc.get_member("unknown-org") + assert member is None + + @pytest.mark.asyncio + async def test_sends_correct_url(self): + mock_client = MagicMock() + mock_client.get = AsyncMock(return_value=_mock_response(404)) + + rc = RegistryClient( + base_url="https://test.example.com", + client=mock_client, + user_agent="test-agent", + ) + await rc.get_member("adgentek") + + mock_client.get.assert_called_once_with( + "https://test.example.com/api/members/adgentek", + headers={"User-Agent": "test-agent"}, + timeout=10.0, + ) + + @pytest.mark.asyncio + async def test_raises_on_server_error(self): + mock_client = MagicMock() + mock_client.get = AsyncMock(return_value=_mock_response(500)) + + rc = RegistryClient(client=mock_client) + with pytest.raises(RegistryError) as exc_info: + await rc.get_member("adgentek") + assert exc_info.value.status_code == 500 + + @pytest.mark.asyncio + async def test_raises_on_timeout(self): + mock_client = MagicMock() + mock_client.get = AsyncMock(side_effect=httpx.ReadTimeout("timeout")) + + rc = RegistryClient(client=mock_client) + with pytest.raises(RegistryError, match="timed out"): + await rc.get_member("adgentek") + + @pytest.mark.asyncio + async def test_raises_on_invalid_response_data(self): + mock_client = MagicMock() + mock_client.get = AsyncMock( + return_value=_mock_response(200, {"unexpected": "data"}) + ) + + rc = RegistryClient(client=mock_client) + with pytest.raises(RegistryError, match="invalid response"): + await rc.get_member("adgentek") + + class TestRegistryTypes: - """Test ResolvedBrand and ResolvedProperty Pydantic models.""" + """Test ResolvedBrand, ResolvedProperty, and Member Pydantic models.""" def test_resolved_brand_validates(self): brand = ResolvedBrand.model_validate(BRAND_DATA) @@ -413,8 +643,31 @@ def test_resolved_brand_optional_fields(self): brand = ResolvedBrand.model_validate(minimal) assert brand.keller_type is None assert brand.brand_manifest is None + assert brand.brand is None assert brand.house_domain is None + def test_resolved_brand_new_field_populates_brand_manifest(self): + """New API returns 'brand' field; brand_manifest must still be accessible.""" + brand = ResolvedBrand.model_validate(BRAND_DATA_NEW) + assert brand.brand == {"name": "Nike"} + assert brand.brand_manifest == {"name": "Nike"} + + def test_resolved_brand_old_field_populates_brand(self): + """Old API returns 'brand_manifest'; brand field must be populated too.""" + brand = ResolvedBrand.model_validate(BRAND_DATA) + assert brand.brand_manifest == {"name": "Nike"} + assert brand.brand == {"name": "Nike"} + + def test_resolved_brand_both_fields_present(self): + """When both fields are present, each keeps its own value.""" + data = { + **BRAND_DATA, + "brand": {"name": "Nike (brand.json)"}, + } + brand = ResolvedBrand.model_validate(data) + assert brand.brand_manifest == {"name": "Nike"} + assert brand.brand == {"name": "Nike (brand.json)"} + def test_resolved_property_validates(self): prop = ResolvedProperty.model_validate(PROPERTY_DATA) assert prop.publisher_domain == "nytimes.com" @@ -426,6 +679,25 @@ def test_resolved_property_all_fields(self): assert len(prop.authorized_agents) == 1 assert len(prop.properties) == 1 + def test_member_validates(self): + member = Member.model_validate(MEMBER_DATA) + assert member.slug == "adgentek" + assert member.display_name == "Adgentek" + assert member.is_founding_member is True + assert len(member.offerings) == 3 + + def test_member_defaults(self): + minimal = { + "id": "abc123", + "slug": "test-org", + "display_name": "Test Org", + } + member = Member.model_validate(minimal) + assert member.offerings == [] + assert member.markets == [] + assert member.is_public is True + assert member.si_enabled is False + class TestPublicApiExports: """Test that registry types are exported from the adcp package.""" @@ -460,6 +732,16 @@ def test_resolved_property_exported_from_root(self): assert adcp.ResolvedProperty is ResolvedProperty + def test_member_exported_from_types(self): + import adcp.types + + assert adcp.types.Member is Member + + def test_member_exported_from_root(self): + import adcp + + assert adcp.Member is Member + class TestRegistryError: """Test RegistryError exception.""" diff --git a/tests/test_type_coercion.py b/tests/test_type_coercion.py index a4be8607..e9397e9f 100644 --- a/tests/test_type_coercion.py +++ b/tests/test_type_coercion.py @@ -134,7 +134,7 @@ def test_fields_accepts_string_list(self): assert len(req.fields) == 3 assert req.fields[0] == FieldModel.creative_id assert req.fields[1] == FieldModel.name - assert req.fields[2] == FieldModel.format_ # format_ to avoid Python keyword collision + assert req.fields[2] == FieldModel.format assert all(isinstance(x, FieldModel) for x in req.fields) def test_fields_accepts_enum_list(self): @@ -299,7 +299,7 @@ def test_create_media_buy_accepts_extended_packages(self): """CreateMediaBuyRequest.packages accepts PackageRequest subclass instances.""" from datetime import datetime, timezone - from pydantic import AnyUrl, Field + from pydantic import Field from adcp.types import CreateMediaBuyRequest, PackageRequest @@ -320,7 +320,7 @@ class ExtendedPackage(PackageRequest): # No cast() needed! request = CreateMediaBuyRequest( account_id="acct-1", - brand_manifest=AnyUrl("https://example.com/manifest.json"), # URL reference + brand={"domain": "example.com"}, buyer_ref="buyer-ref", start_time=datetime.now(timezone.utc), end_time=datetime(2025, 12, 31, tzinfo=timezone.utc),