adcp 2.18.0__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. adcp/ADCP_VERSION +1 -1
  2. adcp/__init__.py +6 -14
  3. adcp/__main__.py +94 -51
  4. adcp/adagents.py +91 -19
  5. adcp/client.py +865 -0
  6. adcp/protocols/a2a.py +84 -0
  7. adcp/protocols/base.py +101 -0
  8. adcp/protocols/mcp.py +87 -1
  9. adcp/server/__init__.py +49 -0
  10. adcp/server/base.py +368 -0
  11. adcp/server/content_standards.py +561 -0
  12. adcp/server/governance.py +491 -0
  13. adcp/server/mcp_tools.py +471 -0
  14. adcp/server/proposal.py +334 -0
  15. adcp/server/sponsored_intelligence.py +444 -0
  16. adcp/types/__init__.py +111 -23
  17. adcp/types/_ergonomic.py +35 -18
  18. adcp/types/_generated.py +419 -44
  19. adcp/types/aliases.py +13 -20
  20. adcp/types/base.py +1 -1
  21. adcp/types/generated_poc/adagents.py +103 -6
  22. adcp/types/generated_poc/content_standards/__init__.py +3 -0
  23. adcp/types/generated_poc/content_standards/artifact.py +208 -0
  24. adcp/types/generated_poc/content_standards/artifact_webhook_payload.py +64 -0
  25. adcp/types/generated_poc/content_standards/calibrate_content_request.py +17 -0
  26. adcp/types/generated_poc/content_standards/calibrate_content_response.py +74 -0
  27. adcp/types/generated_poc/content_standards/content_standards.py +66 -0
  28. adcp/types/generated_poc/content_standards/create_content_standards_request.py +97 -0
  29. adcp/types/generated_poc/content_standards/create_content_standards_response.py +52 -0
  30. adcp/types/generated_poc/content_standards/get_content_standards_request.py +21 -0
  31. adcp/types/generated_poc/content_standards/get_content_standards_response.py +43 -0
  32. adcp/types/generated_poc/content_standards/get_media_buy_artifacts_request.py +64 -0
  33. adcp/types/generated_poc/content_standards/get_media_buy_artifacts_response.py +117 -0
  34. adcp/types/generated_poc/content_standards/list_content_standards_request.py +31 -0
  35. adcp/types/generated_poc/content_standards/list_content_standards_response.py +48 -0
  36. adcp/types/generated_poc/content_standards/update_content_standards_request.py +101 -0
  37. adcp/types/generated_poc/content_standards/update_content_standards_response.py +34 -0
  38. adcp/types/generated_poc/content_standards/validate_content_delivery_request.py +59 -0
  39. adcp/types/generated_poc/content_standards/validate_content_delivery_response.py +85 -0
  40. adcp/types/generated_poc/core/activation_key.py +1 -1
  41. adcp/types/generated_poc/core/assets/audio_asset.py +1 -1
  42. adcp/types/generated_poc/core/assets/css_asset.py +1 -1
  43. adcp/types/generated_poc/core/assets/daast_asset.py +1 -1
  44. adcp/types/generated_poc/core/assets/html_asset.py +1 -1
  45. adcp/types/generated_poc/core/assets/image_asset.py +1 -1
  46. adcp/types/generated_poc/core/assets/javascript_asset.py +1 -1
  47. adcp/types/generated_poc/core/assets/text_asset.py +1 -1
  48. adcp/types/generated_poc/core/assets/url_asset.py +1 -1
  49. adcp/types/generated_poc/core/assets/vast_asset.py +1 -1
  50. adcp/types/generated_poc/core/assets/video_asset.py +1 -1
  51. adcp/types/generated_poc/core/assets/webhook_asset.py +1 -1
  52. adcp/types/generated_poc/core/async_response_data.py +1 -1
  53. adcp/types/generated_poc/core/brand_manifest.py +68 -5
  54. adcp/types/generated_poc/core/brand_manifest_ref.py +1 -1
  55. adcp/types/generated_poc/core/context.py +1 -1
  56. adcp/types/generated_poc/core/creative_asset.py +8 -7
  57. adcp/types/generated_poc/core/creative_assignment.py +1 -1
  58. adcp/types/generated_poc/core/creative_filters.py +4 -14
  59. adcp/types/generated_poc/core/creative_manifest.py +1 -1
  60. adcp/types/generated_poc/core/creative_policy.py +1 -1
  61. adcp/types/generated_poc/core/delivery_metrics.py +1 -1
  62. adcp/types/generated_poc/core/deployment.py +1 -1
  63. adcp/types/generated_poc/core/destination.py +1 -1
  64. adcp/types/generated_poc/core/error.py +1 -1
  65. adcp/types/generated_poc/core/ext.py +1 -1
  66. adcp/types/generated_poc/core/format.py +6 -5
  67. adcp/types/generated_poc/core/format_id.py +1 -1
  68. adcp/types/generated_poc/core/frequency_cap.py +1 -1
  69. adcp/types/generated_poc/core/identifier.py +27 -0
  70. adcp/types/generated_poc/core/mcp_webhook_payload.py +1 -1
  71. adcp/types/generated_poc/core/measurement.py +1 -1
  72. adcp/types/generated_poc/core/media_buy.py +1 -1
  73. adcp/types/generated_poc/core/media_buy_features.py +29 -0
  74. adcp/types/generated_poc/core/offering.py +80 -0
  75. adcp/types/generated_poc/core/package.py +1 -1
  76. adcp/types/generated_poc/core/performance_feedback.py +1 -1
  77. adcp/types/generated_poc/core/placement.py +1 -1
  78. adcp/types/generated_poc/core/pricing_option.py +8 -14
  79. adcp/types/generated_poc/core/product.py +1 -1
  80. adcp/types/generated_poc/core/product_allocation.py +48 -0
  81. adcp/types/generated_poc/core/product_filters.py +72 -7
  82. adcp/types/generated_poc/core/promoted_offerings.py +12 -21
  83. adcp/types/generated_poc/core/promoted_products.py +1 -1
  84. adcp/types/generated_poc/core/property.py +1 -1
  85. adcp/types/generated_poc/core/property_id.py +1 -1
  86. adcp/types/generated_poc/core/property_list_ref.py +26 -0
  87. adcp/types/generated_poc/core/property_tag.py +1 -1
  88. adcp/types/generated_poc/core/proposal.py +64 -0
  89. adcp/types/generated_poc/core/protocol_envelope.py +1 -1
  90. adcp/types/generated_poc/core/publisher_property_selector.py +1 -1
  91. adcp/types/generated_poc/core/push_notification_config.py +1 -1
  92. adcp/types/generated_poc/core/reporting_capabilities.py +1 -1
  93. adcp/types/generated_poc/core/reporting_webhook.py +70 -0
  94. adcp/types/generated_poc/core/response.py +1 -1
  95. adcp/types/generated_poc/core/signal_filters.py +1 -1
  96. adcp/types/generated_poc/core/start_timing.py +4 -4
  97. adcp/types/generated_poc/core/sub_asset.py +1 -1
  98. adcp/types/generated_poc/core/targeting.py +55 -14
  99. adcp/types/generated_poc/creative/list_creative_formats_request.py +1 -1
  100. adcp/types/generated_poc/creative/list_creative_formats_response.py +1 -1
  101. adcp/types/generated_poc/creative/preview_creative_request.py +1 -1
  102. adcp/types/generated_poc/creative/preview_creative_response.py +3 -2
  103. adcp/types/generated_poc/creative/preview_render.py +1 -1
  104. adcp/types/generated_poc/enums/adcp_domain.py +3 -1
  105. adcp/types/generated_poc/enums/asset_content_type.py +1 -1
  106. adcp/types/generated_poc/enums/auth_scheme.py +1 -1
  107. adcp/types/generated_poc/enums/available_metric.py +1 -1
  108. adcp/types/generated_poc/enums/channels.py +18 -8
  109. adcp/types/generated_poc/enums/co_branding_requirement.py +1 -1
  110. adcp/types/generated_poc/enums/creative_action.py +1 -1
  111. adcp/types/generated_poc/enums/creative_agent_capability.py +1 -1
  112. adcp/types/generated_poc/enums/creative_sort_field.py +1 -1
  113. adcp/types/generated_poc/enums/creative_status.py +2 -1
  114. adcp/types/generated_poc/enums/daast_tracking_event.py +1 -1
  115. adcp/types/generated_poc/enums/daast_version.py +1 -1
  116. adcp/types/generated_poc/enums/delivery_type.py +1 -1
  117. adcp/types/generated_poc/enums/dimension_unit.py +1 -1
  118. adcp/types/generated_poc/enums/feed_format.py +1 -1
  119. adcp/types/generated_poc/enums/feedback_source.py +1 -1
  120. adcp/types/generated_poc/enums/format_category.py +1 -1
  121. adcp/types/generated_poc/enums/format_id_parameter.py +1 -1
  122. adcp/types/generated_poc/enums/frequency_cap_scope.py +1 -1
  123. adcp/types/generated_poc/enums/geo_level.py +14 -0
  124. adcp/types/generated_poc/enums/history_entry_type.py +1 -1
  125. adcp/types/generated_poc/enums/http_method.py +1 -1
  126. adcp/types/generated_poc/enums/identifier_types.py +1 -1
  127. adcp/types/generated_poc/enums/javascript_module_type.py +1 -1
  128. adcp/types/generated_poc/enums/landing_page_requirement.py +1 -1
  129. adcp/types/generated_poc/enums/markdown_flavor.py +1 -1
  130. adcp/types/generated_poc/enums/media_buy_status.py +1 -1
  131. adcp/types/generated_poc/enums/metric_type.py +1 -1
  132. adcp/types/generated_poc/enums/metro_system.py +15 -0
  133. adcp/types/generated_poc/enums/notification_type.py +1 -1
  134. adcp/types/generated_poc/enums/pacing.py +1 -1
  135. adcp/types/generated_poc/enums/postal_system.py +19 -0
  136. adcp/types/generated_poc/enums/preview_output_format.py +1 -1
  137. adcp/types/generated_poc/enums/pricing_model.py +1 -1
  138. adcp/types/generated_poc/enums/property_type.py +2 -1
  139. adcp/types/generated_poc/enums/publisher_identifier_types.py +1 -1
  140. adcp/types/generated_poc/enums/reporting_frequency.py +1 -1
  141. adcp/types/generated_poc/enums/signal_catalog_type.py +1 -1
  142. adcp/types/generated_poc/enums/sort_direction.py +1 -1
  143. adcp/types/generated_poc/enums/task_status.py +1 -1
  144. adcp/types/generated_poc/enums/task_type.py +7 -1
  145. adcp/types/generated_poc/enums/update_frequency.py +1 -1
  146. adcp/types/generated_poc/enums/url_asset_type.py +1 -1
  147. adcp/types/generated_poc/enums/validation_mode.py +1 -1
  148. adcp/types/generated_poc/enums/vast_tracking_event.py +1 -1
  149. adcp/types/generated_poc/enums/vast_version.py +1 -1
  150. adcp/types/generated_poc/enums/webhook_response_type.py +1 -1
  151. adcp/types/generated_poc/enums/webhook_security_method.py +1 -1
  152. adcp/types/generated_poc/extensions/__init__.py +3 -0
  153. adcp/types/generated_poc/extensions/extension_meta.py +58 -0
  154. adcp/types/generated_poc/media_buy/build_creative_request.py +1 -1
  155. adcp/types/generated_poc/media_buy/build_creative_response.py +1 -1
  156. adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py +1 -1
  157. adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py +1 -1
  158. adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py +1 -1
  159. adcp/types/generated_poc/media_buy/create_media_buy_request.py +54 -26
  160. adcp/types/generated_poc/media_buy/create_media_buy_response.py +1 -1
  161. adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py +1 -1
  162. adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py +1 -1
  163. adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py +1 -1
  164. adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py +1 -1
  165. adcp/types/generated_poc/media_buy/get_products_async_response_working.py +1 -1
  166. adcp/types/generated_poc/media_buy/get_products_request.py +18 -3
  167. adcp/types/generated_poc/media_buy/get_products_response.py +14 -2
  168. adcp/types/generated_poc/media_buy/list_authorized_properties_request.py +1 -1
  169. adcp/types/generated_poc/media_buy/list_authorized_properties_response.py +2 -2
  170. adcp/types/generated_poc/media_buy/list_creative_formats_request.py +1 -1
  171. adcp/types/generated_poc/media_buy/list_creative_formats_response.py +1 -1
  172. adcp/types/generated_poc/media_buy/list_creatives_request.py +2 -2
  173. adcp/types/generated_poc/media_buy/list_creatives_response.py +7 -10
  174. adcp/types/generated_poc/media_buy/package_request.py +15 -6
  175. adcp/types/generated_poc/media_buy/package_update.py +119 -0
  176. adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py +1 -1
  177. adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py +1 -1
  178. adcp/types/generated_poc/media_buy/sync_creatives_async_response_input_required.py +1 -1
  179. adcp/types/generated_poc/media_buy/sync_creatives_async_response_submitted.py +1 -1
  180. adcp/types/generated_poc/media_buy/sync_creatives_async_response_working.py +1 -1
  181. adcp/types/generated_poc/media_buy/sync_creatives_request.py +1 -1
  182. adcp/types/generated_poc/media_buy/sync_creatives_response.py +1 -1
  183. adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py +1 -1
  184. adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py +1 -1
  185. adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py +1 -1
  186. adcp/types/generated_poc/media_buy/update_media_buy_request.py +20 -108
  187. adcp/types/generated_poc/media_buy/update_media_buy_response.py +1 -1
  188. adcp/types/generated_poc/pricing_options/cpc_option.py +35 -10
  189. adcp/types/generated_poc/pricing_options/cpcv_option.py +35 -10
  190. adcp/types/generated_poc/pricing_options/{cpm_auction_option.py → cpm_option.py} +23 -19
  191. adcp/types/generated_poc/pricing_options/cpp_option.py +39 -16
  192. adcp/types/generated_poc/pricing_options/cpv_option.py +37 -18
  193. adcp/types/generated_poc/pricing_options/flat_rate_option.py +45 -39
  194. adcp/types/generated_poc/pricing_options/{vcpm_auction_option.py → vcpm_option.py} +23 -14
  195. adcp/types/generated_poc/property/__init__.py +3 -0
  196. adcp/types/generated_poc/property/base_property_source.py +86 -0
  197. adcp/types/generated_poc/property/create_property_list_request.py +43 -0
  198. adcp/types/generated_poc/property/create_property_list_response.py +27 -0
  199. adcp/types/generated_poc/property/delete_property_list_request.py +22 -0
  200. adcp/types/generated_poc/property/delete_property_list_response.py +21 -0
  201. adcp/types/generated_poc/property/feature_requirement.py +42 -0
  202. adcp/types/generated_poc/property/get_property_list_request.py +34 -0
  203. adcp/types/generated_poc/property/get_property_list_response.py +61 -0
  204. adcp/types/generated_poc/property/list_property_lists_request.py +29 -0
  205. adcp/types/generated_poc/property/list_property_lists_response.py +39 -0
  206. adcp/types/generated_poc/property/property_error.py +33 -0
  207. adcp/types/generated_poc/property/property_feature.py +22 -0
  208. adcp/types/generated_poc/property/property_feature_definition.py +80 -0
  209. adcp/types/generated_poc/property/property_list.py +62 -0
  210. adcp/types/generated_poc/property/property_list_changed_webhook.py +51 -0
  211. adcp/types/generated_poc/property/property_list_filters.py +47 -0
  212. adcp/types/generated_poc/property/update_property_list_request.py +46 -0
  213. adcp/types/generated_poc/property/update_property_list_response.py +21 -0
  214. adcp/types/generated_poc/protocol/__init__.py +3 -0
  215. adcp/types/generated_poc/protocol/get_adcp_capabilities_request.py +34 -0
  216. adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py +353 -0
  217. adcp/types/generated_poc/protocols/adcp_extension.py +18 -5
  218. adcp/types/generated_poc/signals/activate_signal_request.py +1 -1
  219. adcp/types/generated_poc/signals/activate_signal_response.py +1 -1
  220. adcp/types/generated_poc/signals/get_signals_request.py +1 -1
  221. adcp/types/generated_poc/signals/get_signals_response.py +1 -1
  222. adcp/types/generated_poc/sponsored_intelligence/__init__.py +3 -0
  223. adcp/types/generated_poc/sponsored_intelligence/si_capabilities.py +102 -0
  224. adcp/types/generated_poc/sponsored_intelligence/si_get_offering_request.py +34 -0
  225. adcp/types/generated_poc/sponsored_intelligence/si_get_offering_response.py +100 -0
  226. adcp/types/generated_poc/sponsored_intelligence/si_identity.py +78 -0
  227. adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_request.py +46 -0
  228. adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_response.py +44 -0
  229. adcp/types/generated_poc/sponsored_intelligence/si_send_message_request.py +58 -0
  230. adcp/types/generated_poc/sponsored_intelligence/si_send_message_response.py +101 -0
  231. adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_request.py +60 -0
  232. adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_response.py +54 -0
  233. adcp/types/generated_poc/sponsored_intelligence/si_ui_element.py +30 -0
  234. adcp/utils/format_assets.py +5 -5
  235. adcp/utils/preview_cache.py +2 -2
  236. {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/METADATA +1 -1
  237. adcp-3.0.0.dist-info/RECORD +264 -0
  238. {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/WHEEL +1 -1
  239. adcp/types/generated_poc/enums/standard_format_ids.py +0 -45
  240. adcp/types/generated_poc/pricing_options/cpm_fixed_option.py +0 -43
  241. adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py +0 -47
  242. adcp-2.18.0.dist-info/RECORD +0 -195
  243. {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/entry_points.txt +0 -0
  244. {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/licenses/LICENSE +0 -0
  245. {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/top_level.txt +0 -0
adcp/types/aliases.py CHANGED
@@ -35,9 +35,6 @@ from adcp.types._generated import (
35
35
  # Activation responses
36
36
  ActivateSignalResponse1,
37
37
  ActivateSignalResponse2,
38
- # Activation keys
39
- ActivationKey1,
40
- ActivationKey2,
41
38
  # Authorized agents
42
39
  AuthorizedAgents,
43
40
  AuthorizedAgents1,
@@ -64,10 +61,10 @@ from adcp.types._generated import (
64
61
  # Preview creative responses
65
62
  PreviewCreativeResponse1,
66
63
  PreviewCreativeResponse2,
67
- # Preview renders
68
- PreviewRender1,
69
- PreviewRender2,
70
- PreviewRender3,
64
+ # Preview renders (discriminated union by output_format)
65
+ PreviewRender1, # output_format='url'
66
+ PreviewRender2, # output_format='html'
67
+ PreviewRender3, # output_format='both'
71
68
  # Publisher properties types
72
69
  PropertyId,
73
70
  PropertyTag,
@@ -198,12 +195,11 @@ UpdateMediaBuyPropertiesRequest = UpdateMediaBuyRequest2
198
195
  # ============================================================================
199
196
  # ACTIVATION KEY ALIASES
200
197
  # ============================================================================
201
-
202
- PropertyIdActivationKey = ActivationKey1
203
- """Activation key using property_id for identification."""
204
-
205
- PropertyTagActivationKey = ActivationKey2
206
- """Activation key using property_tags for identification."""
198
+ # Note: Activation key schema changed from property_id/property_tag variants
199
+ # to segment_id/key_value variants. Import directly from _generated:
200
+ # from adcp.types._generated import ActivationKey1 as SegmentIdActivationKey
201
+ # from adcp.types._generated import ActivationKey2 as KeyValueActivationKey
202
+ # These will be added once the types are regenerated with proper schema.
207
203
 
208
204
  # ============================================================================
209
205
  # PREVIEW/RENDER TYPE ALIASES
@@ -216,15 +212,15 @@ PreviewCreativeStaticResponse = PreviewCreativeResponse1
216
212
  PreviewCreativeInteractiveResponse = PreviewCreativeResponse2
217
213
  """Preview response with interactive renders (iframe embedding)."""
218
214
 
219
- # Preview Render Variants (discriminated by output_format)
215
+ # Preview Render Aliases (discriminated union by output_format)
220
216
  UrlPreviewRender = PreviewRender1
221
- """Preview render with output_format='url' - provides preview_url for iframe embedding."""
217
+ """Preview render with output_format='url' and preview_url for iframe embedding."""
222
218
 
223
219
  HtmlPreviewRender = PreviewRender2
224
- """Preview render with output_format='html' - provides preview_html for direct embedding."""
220
+ """Preview render with output_format='html' and preview_html for direct embedding."""
225
221
 
226
222
  BothPreviewRender = PreviewRender3
227
- """Preview render with output_format='both' - provides both preview_url and preview_html."""
223
+ """Preview render with output_format='both' and both preview_url and preview_html."""
228
224
 
229
225
  # ============================================================================
230
226
  # ASSET TYPE ALIASES - Delivery & Kind Discriminated Unions
@@ -700,9 +696,6 @@ __all__ = [
700
696
  # Activation responses
701
697
  "ActivateSignalSuccessResponse",
702
698
  "ActivateSignalErrorResponse",
703
- # Activation keys
704
- "PropertyIdActivationKey",
705
- "PropertyTagActivationKey",
706
699
  # Asset type aliases
707
700
  "BothPreviewRender",
708
701
  "HtmlPreviewRender",
adcp/types/base.py CHANGED
@@ -204,7 +204,7 @@ class AdCPBaseModel(BaseModel):
204
204
  kwargs["exclude_none"] = True
205
205
  return super().model_dump_json(**kwargs)
206
206
 
207
- def summary(self) -> str:
207
+ def model_summary(self) -> str:
208
208
  """Human-readable summary for protocol responses.
209
209
 
210
210
  Returns a standardized human-readable message suitable for MCP tool
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: adagents.json
3
- # timestamp: 2026-01-08T19:25:24+00:00
3
+ # timestamp: 2026-01-26T13:22:19+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -59,6 +59,12 @@ class Contact(AdCPBaseModel):
59
59
  min_length=1,
60
60
  ),
61
61
  ]
62
+ privacy_policy_url: Annotated[
63
+ AnyUrl | None,
64
+ Field(
65
+ description="URL to the entity's privacy policy. Used for consumer consent flows when interacting with this sales agent."
66
+ ),
67
+ ] = None
62
68
  seller_id: Annotated[
63
69
  str | None,
64
70
  Field(
@@ -77,6 +83,32 @@ class Contact(AdCPBaseModel):
77
83
  ] = None
78
84
 
79
85
 
86
+ class PropertyFeature(AdCPBaseModel):
87
+ model_config = ConfigDict(
88
+ extra='allow',
89
+ )
90
+ features: Annotated[
91
+ list[str],
92
+ Field(
93
+ description="Feature IDs this agent provides (e.g., 'carbon_score', 'tag_certified_against_fraud'). Use list_property_features on the agent for full definitions.",
94
+ min_length=1,
95
+ ),
96
+ ]
97
+ name: Annotated[
98
+ str,
99
+ Field(
100
+ description="Human-readable name of the vendor/agent (e.g., 'Scope3', 'TAG', 'OneTrust')"
101
+ ),
102
+ ]
103
+ publisher_id: Annotated[
104
+ str | None, Field(description='Optional publisher identifier at this agent (for lookup)')
105
+ ] = None
106
+ url: Annotated[
107
+ AnyUrl,
108
+ Field(description="The agent's API endpoint URL (must implement get_property_features)"),
109
+ ]
110
+
111
+
80
112
  class Tags(AdCPBaseModel):
81
113
  model_config = ConfigDict(
82
114
  extra='allow',
@@ -223,6 +255,12 @@ class AuthorizedSalesAgents2(AdCPBaseModel):
223
255
  min_length=1,
224
256
  ),
225
257
  ] = None
258
+ property_features: Annotated[
259
+ list[PropertyFeature] | None,
260
+ Field(
261
+ description="[AdCP 3.0] Optional list of agents that provide property feature data (certifications, scores, compliance status). Used for discovery - actual data comes from querying the agent's get_property_features task."
262
+ ),
263
+ ] = None
226
264
  tags: Annotated[
227
265
  dict[str, Tags] | None,
228
266
  Field(
@@ -238,12 +276,12 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
238
276
  description='Declaration of authorized sales agents for advertising inventory. Hosted at /.well-known/adagents.json on publisher domains. Can either contain the full structure inline or reference an authoritative URL.',
239
277
  examples=[
240
278
  {
241
- '$schema': '/schemas/2.6.0/adagents.json',
279
+ '$schema': '/schemas/3.0.0-beta.1/adagents.json',
242
280
  'authoritative_location': 'https://cdn.example.com/adagents/v2/adagents.json',
243
281
  'last_updated': '2025-01-15T10:00:00Z',
244
282
  },
245
283
  {
246
- '$schema': '/schemas/2.6.0/adagents.json',
284
+ '$schema': '/schemas/3.0.0-beta.1/adagents.json',
247
285
  'authorized_agents': [
248
286
  {
249
287
  'authorization_type': 'property_tags',
@@ -269,7 +307,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
269
307
  },
270
308
  },
271
309
  {
272
- '$schema': '/schemas/2.6.0/adagents.json',
310
+ '$schema': '/schemas/3.0.0-beta.1/adagents.json',
273
311
  'authorized_agents': [
274
312
  {
275
313
  'authorization_type': 'property_tags',
@@ -282,6 +320,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
282
320
  'domain': 'meta.com',
283
321
  'email': 'adops@meta.com',
284
322
  'name': 'Meta Advertising Operations',
323
+ 'privacy_policy_url': 'https://www.meta.com/privacy/policy',
285
324
  'seller_id': 'pub-meta-12345',
286
325
  'tag_id': '12345',
287
326
  },
@@ -334,7 +373,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
334
373
  },
335
374
  },
336
375
  {
337
- '$schema': '/schemas/2.6.0/adagents.json',
376
+ '$schema': '/schemas/3.0.0-beta.1/adagents.json',
338
377
  'authorized_agents': [
339
378
  {
340
379
  'authorization_type': 'property_tags',
@@ -362,7 +401,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
362
401
  },
363
402
  },
364
403
  {
365
- '$schema': '/schemas/2.6.0/adagents.json',
404
+ '$schema': '/schemas/3.0.0-beta.1/adagents.json',
366
405
  'authorized_agents': [
367
406
  {
368
407
  'authorization_type': 'publisher_properties',
@@ -401,6 +440,64 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
401
440
  },
402
441
  'last_updated': '2025-01-10T17:00:00Z',
403
442
  },
443
+ {
444
+ '$schema': '/schemas/3.0.0-beta.1/adagents.json',
445
+ 'authorized_agents': [
446
+ {
447
+ 'authorization_type': 'property_tags',
448
+ 'authorized_for': 'All news properties',
449
+ 'property_tags': ['news'],
450
+ 'url': 'https://sales.news.example.com',
451
+ }
452
+ ],
453
+ 'contact': {
454
+ 'domain': 'news.example.com',
455
+ 'email': 'adops@news.example.com',
456
+ 'name': 'Premium News Publisher',
457
+ },
458
+ 'last_updated': '2025-01-10T18:00:00Z',
459
+ 'properties': [
460
+ {
461
+ 'identifiers': [{'type': 'domain', 'value': 'news.example.com'}],
462
+ 'name': 'News Example',
463
+ 'property_type': 'website',
464
+ 'publisher_domain': 'news.example.com',
465
+ 'tags': ['premium', 'news'],
466
+ }
467
+ ],
468
+ 'property_features': [
469
+ {
470
+ 'features': ['carbon_score', 'sustainability_grade'],
471
+ 'name': 'Scope3',
472
+ 'publisher_id': 'pub_news_12345',
473
+ 'url': 'https://api.scope3.com',
474
+ },
475
+ {
476
+ 'features': [
477
+ 'tag_certified_against_fraud',
478
+ 'tag_brand_safety_certified',
479
+ ],
480
+ 'name': 'TAG',
481
+ 'url': 'https://api.tagtoday.net',
482
+ },
483
+ {
484
+ 'features': ['gdpr_compliant', 'tcf_registered', 'ccpa_compliant'],
485
+ 'name': 'OneTrust',
486
+ 'publisher_id': 'ot_news_67890',
487
+ 'url': 'https://api.onetrust.com',
488
+ },
489
+ ],
490
+ 'tags': {
491
+ 'news': {
492
+ 'description': 'News and journalism content',
493
+ 'name': 'News Properties',
494
+ },
495
+ 'premium': {
496
+ 'description': 'High-quality, brand-safe properties',
497
+ 'name': 'Premium Properties',
498
+ },
499
+ },
500
+ },
404
501
  ],
405
502
  title='Authorized Sales Agents',
406
503
  ),
@@ -0,0 +1,3 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: .schema_temp
3
+ # timestamp: 2026-01-25T21:17:54+00:00
@@ -0,0 +1,208 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: content_standards/artifact.json
3
+ # timestamp: 2026-01-25T21:17:54+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+ from typing import Annotated, Any, Literal
9
+
10
+ from adcp.types.base import AdCPBaseModel
11
+ from pydantic import AnyUrl, AwareDatetime, ConfigDict, Field, RootModel
12
+
13
+ from ..core import format_id as format_id_1
14
+ from ..core import identifier
15
+
16
+
17
+ class Role(Enum):
18
+ title_ = 'title'
19
+ paragraph = 'paragraph'
20
+ heading = 'heading'
21
+ caption = 'caption'
22
+ quote = 'quote'
23
+ list_item = 'list_item'
24
+ description = 'description'
25
+
26
+
27
+ class Assets(AdCPBaseModel):
28
+ content: Annotated[str, Field(description='Text content')]
29
+ heading_level: Annotated[
30
+ int | None, Field(description='Heading level (1-6), only for role=heading', ge=1, le=6)
31
+ ] = None
32
+ language: Annotated[
33
+ str | None,
34
+ Field(
35
+ description="BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content."
36
+ ),
37
+ ] = None
38
+ role: Annotated[
39
+ Role | None,
40
+ Field(
41
+ description="Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries."
42
+ ),
43
+ ] = None
44
+ type: Literal['text']
45
+
46
+
47
+ class TranscriptSource(Enum):
48
+ original_script = 'original_script'
49
+ subtitles = 'subtitles'
50
+ closed_captions = 'closed_captions'
51
+ dub = 'dub'
52
+ generated = 'generated'
53
+
54
+
55
+ class TranscriptSource1(Enum):
56
+ original_script = 'original_script'
57
+ closed_captions = 'closed_captions'
58
+ generated = 'generated'
59
+
60
+
61
+ class Identifiers(AdCPBaseModel):
62
+ model_config = ConfigDict(
63
+ extra='allow',
64
+ )
65
+ apple_podcast_id: Annotated[str | None, Field(description='Apple Podcasts ID')] = None
66
+ podcast_guid: Annotated[str | None, Field(description='Podcast GUID (from RSS feed)')] = None
67
+ rss_url: Annotated[AnyUrl | None, Field(description='RSS feed URL')] = None
68
+ spotify_show_id: Annotated[str | None, Field(description='Spotify show ID')] = None
69
+ youtube_video_id: Annotated[str | None, Field(description='YouTube video ID')] = None
70
+
71
+
72
+ class Metadata(AdCPBaseModel):
73
+ model_config = ConfigDict(
74
+ extra='allow',
75
+ )
76
+ author: Annotated[str | None, Field(description='Artifact author name')] = None
77
+ canonical: Annotated[AnyUrl | None, Field(description='Canonical URL')] = None
78
+ json_ld: Annotated[
79
+ list[dict[str, Any]] | None, Field(description='JSON-LD structured data (schema.org)')
80
+ ] = None
81
+ keywords: Annotated[str | None, Field(description='Artifact keywords')] = None
82
+ open_graph: Annotated[
83
+ dict[str, Any] | None, Field(description='Open Graph protocol metadata')
84
+ ] = None
85
+ twitter_card: Annotated[dict[str, Any] | None, Field(description='Twitter Card metadata')] = (
86
+ None
87
+ )
88
+
89
+
90
+ class AssetAccess1(AdCPBaseModel):
91
+ method: Literal['bearer_token']
92
+ token: Annotated[str, Field(description='OAuth2 bearer token for Authorization header')]
93
+
94
+
95
+ class Provider(Enum):
96
+ gcp = 'gcp'
97
+ aws = 'aws'
98
+
99
+
100
+ class AssetAccess2(AdCPBaseModel):
101
+ credentials: Annotated[
102
+ dict[str, Any] | None, Field(description='Service account credentials')
103
+ ] = None
104
+ method: Literal['service_account']
105
+ provider: Annotated[Provider, Field(description='Cloud provider')]
106
+
107
+
108
+ class AssetAccess3(AdCPBaseModel):
109
+ method: Literal['signed_url']
110
+
111
+
112
+ class AssetAccess(RootModel[AssetAccess1 | AssetAccess2 | AssetAccess3]):
113
+ root: Annotated[
114
+ AssetAccess1 | AssetAccess2 | AssetAccess3,
115
+ Field(description='Authentication for accessing secured asset URLs'),
116
+ ]
117
+
118
+
119
+ class Assets1(AdCPBaseModel):
120
+ access: Annotated[AssetAccess | None, Field(description='Authentication for secured URLs')] = (
121
+ None
122
+ )
123
+ alt_text: Annotated[str | None, Field(description='Alt text or image description')] = None
124
+ caption: Annotated[str | None, Field(description='Image caption')] = None
125
+ height: Annotated[int | None, Field(description='Image height in pixels')] = None
126
+ type: Literal['image']
127
+ url: Annotated[AnyUrl, Field(description='Image URL')]
128
+ width: Annotated[int | None, Field(description='Image width in pixels')] = None
129
+
130
+
131
+ class Assets2(AdCPBaseModel):
132
+ access: Annotated[AssetAccess | None, Field(description='Authentication for secured URLs')] = (
133
+ None
134
+ )
135
+ duration_ms: Annotated[int | None, Field(description='Video duration in milliseconds')] = None
136
+ thumbnail_url: Annotated[AnyUrl | None, Field(description='Video thumbnail URL')] = None
137
+ transcript: Annotated[str | None, Field(description='Video transcript')] = None
138
+ transcript_source: Annotated[
139
+ TranscriptSource | None, Field(description='How the transcript was generated')
140
+ ] = None
141
+ type: Literal['video']
142
+ url: Annotated[AnyUrl, Field(description='Video URL')]
143
+
144
+
145
+ class Assets3(AdCPBaseModel):
146
+ access: Annotated[AssetAccess | None, Field(description='Authentication for secured URLs')] = (
147
+ None
148
+ )
149
+ duration_ms: Annotated[int | None, Field(description='Audio duration in milliseconds')] = None
150
+ transcript: Annotated[str | None, Field(description='Audio transcript')] = None
151
+ transcript_source: Annotated[
152
+ TranscriptSource1 | None, Field(description='How the transcript was generated')
153
+ ] = None
154
+ type: Literal['audio']
155
+ url: Annotated[AnyUrl, Field(description='Audio URL')]
156
+
157
+
158
+ class Artifact(AdCPBaseModel):
159
+ model_config = ConfigDict(
160
+ extra='allow',
161
+ )
162
+ artifact_id: Annotated[
163
+ str,
164
+ Field(
165
+ description="Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')."
166
+ ),
167
+ ]
168
+ assets: Annotated[
169
+ list[Assets | Assets1 | Assets2 | Assets3],
170
+ Field(
171
+ description='Artifact assets in document flow order - text blocks, images, video, audio'
172
+ ),
173
+ ]
174
+ format_id: Annotated[
175
+ format_id_1.FormatId | None,
176
+ Field(
177
+ description='Optional reference to a format definition. Uses the same format registry as creative formats.'
178
+ ),
179
+ ] = None
180
+ identifiers: Annotated[
181
+ Identifiers | None, Field(description='Platform-specific identifiers for this artifact')
182
+ ] = None
183
+ last_update_time: Annotated[
184
+ AwareDatetime | None,
185
+ Field(description='When the artifact was last modified (ISO 8601 format)'),
186
+ ] = None
187
+ metadata: Annotated[
188
+ Metadata | None, Field(description='Rich metadata extracted from the artifact')
189
+ ] = None
190
+ property_id: Annotated[
191
+ identifier.Identifier,
192
+ Field(description='Identifier for the property where this artifact appears'),
193
+ ]
194
+ published_time: Annotated[
195
+ AwareDatetime | None, Field(description='When the artifact was published (ISO 8601 format)')
196
+ ] = None
197
+ url: Annotated[
198
+ AnyUrl | None,
199
+ Field(
200
+ description='Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes).'
201
+ ),
202
+ ] = None
203
+ variant_id: Annotated[
204
+ str | None,
205
+ Field(
206
+ description="Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique."
207
+ ),
208
+ ] = None
@@ -0,0 +1,64 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: content_standards/artifact_webhook_payload.json
3
+ # timestamp: 2026-01-25T21:17:54+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import AwareDatetime, ConfigDict, Field
11
+
12
+ from ..core import ext as ext_1
13
+ from . import artifact as artifact_1
14
+
15
+
16
+ class Pagination(AdCPBaseModel):
17
+ batch_number: Annotated[int | None, Field(description='Current batch number (1-indexed)')] = (
18
+ None
19
+ )
20
+ total_artifacts: Annotated[
21
+ int | None, Field(description='Total artifacts in the delivery period')
22
+ ] = None
23
+ total_batches: Annotated[
24
+ int | None, Field(description='Total batches for this delivery period')
25
+ ] = None
26
+
27
+
28
+ class Artifact(AdCPBaseModel):
29
+ artifact: Annotated[artifact_1.Artifact, Field(description='The content artifact')]
30
+ delivered_at: Annotated[
31
+ AwareDatetime, Field(description='When the impression was delivered (ISO 8601)')
32
+ ]
33
+ impression_id: Annotated[
34
+ str | None,
35
+ Field(description='Optional impression identifier for correlation with delivery reports'),
36
+ ] = None
37
+ package_id: Annotated[
38
+ str | None, Field(description='Package within the media buy this artifact relates to')
39
+ ] = None
40
+
41
+
42
+ class ArtifactWebhookPayload(AdCPBaseModel):
43
+ model_config = ConfigDict(
44
+ extra='allow',
45
+ )
46
+ artifacts: Annotated[
47
+ list[Artifact], Field(description='Content artifacts from delivered impressions')
48
+ ]
49
+ batch_id: Annotated[
50
+ str,
51
+ Field(
52
+ description='Unique identifier for this batch of artifacts. Use for deduplication and acknowledgment.'
53
+ ),
54
+ ]
55
+ ext: ext_1.ExtensionObject | None = None
56
+ media_buy_id: Annotated[
57
+ str, Field(description='Media buy identifier these artifacts belong to')
58
+ ]
59
+ pagination: Annotated[
60
+ Pagination | None, Field(description='Pagination info when batching large artifact sets')
61
+ ] = None
62
+ timestamp: Annotated[
63
+ AwareDatetime, Field(description='When this batch was generated (ISO 8601)')
64
+ ]
@@ -0,0 +1,17 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: content_standards/calibrate_content_request.json
3
+ # timestamp: 2026-01-25T21:17:54+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import Field
11
+
12
+ from . import artifact as artifact_1
13
+
14
+
15
+ class CalibrateContentRequest(AdCPBaseModel):
16
+ artifact: Annotated[artifact_1.Artifact, Field(description='Artifact to evaluate')]
17
+ standards_id: Annotated[str, Field(description='Standards configuration to calibrate against')]
@@ -0,0 +1,74 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: content_standards/calibrate_content_response.json
3
+ # timestamp: 2026-01-25T21:17:54+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+ from typing import Annotated, Any
9
+
10
+ from adcp.types.base import AdCPBaseModel
11
+ from pydantic import Field, RootModel
12
+
13
+ from ..core import error
14
+
15
+
16
+ class Status(Enum):
17
+ passed = 'passed'
18
+ failed = 'failed'
19
+ warning = 'warning'
20
+ unevaluated = 'unevaluated'
21
+
22
+
23
+ class Feature(AdCPBaseModel):
24
+ explanation: Annotated[
25
+ str | None,
26
+ Field(description='Human-readable explanation of why this feature passed or failed'),
27
+ ] = None
28
+ feature_id: Annotated[
29
+ str,
30
+ Field(
31
+ description='Which feature was evaluated (e.g., brand_safety, brand_suitability, competitor_adjacency)'
32
+ ),
33
+ ]
34
+ status: Annotated[Status, Field(description='Evaluation status for this feature')]
35
+
36
+
37
+ class Verdict(Enum):
38
+ pass_ = 'pass'
39
+ fail = 'fail'
40
+
41
+
42
+ class CalibrateContentResponse1(AdCPBaseModel):
43
+ confidence: Annotated[
44
+ float | None, Field(description='Model confidence in the verdict (0-1)', ge=0.0, le=1.0)
45
+ ] = None
46
+ errors: Annotated[
47
+ Any | None, Field(description='Field must not be present in success response')
48
+ ] = None
49
+ explanation: Annotated[
50
+ str | None, Field(description='Detailed natural language explanation of the decision')
51
+ ] = None
52
+ features: Annotated[
53
+ list[Feature] | None, Field(description='Per-feature breakdown with explanations')
54
+ ] = None
55
+ verdict: Annotated[
56
+ Verdict, Field(description='Overall pass/fail verdict for the content evaluation')
57
+ ]
58
+
59
+
60
+ class CalibrateContentResponse2(AdCPBaseModel):
61
+ errors: list[error.Error]
62
+ verdict: Annotated[
63
+ Any | None, Field(description='Field must not be present in error response')
64
+ ] = None
65
+
66
+
67
+ class CalibrateContentResponse(RootModel[CalibrateContentResponse1 | CalibrateContentResponse2]):
68
+ root: Annotated[
69
+ CalibrateContentResponse1 | CalibrateContentResponse2,
70
+ Field(
71
+ description='Response payload with verdict and detailed explanations for collaborative calibration',
72
+ title='Calibrate Content Response',
73
+ ),
74
+ ]