adcp 2.11.1__py3-none-any.whl → 2.12.1__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 (170) hide show
  1. adcp/ADCP_VERSION +1 -0
  2. adcp/__init__.py +24 -3
  3. adcp/__main__.py +31 -3
  4. adcp/client.py +16 -0
  5. adcp/protocols/a2a.py +178 -25
  6. adcp/protocols/base.py +23 -4
  7. adcp/protocols/mcp.py +44 -0
  8. adcp/types/__init__.py +2 -26
  9. adcp/types/_generated.py +179 -158
  10. adcp/types/generated_poc/adagents.py +221 -25
  11. adcp/types/generated_poc/core/__init__.py +3 -0
  12. adcp/types/generated_poc/{activation_key.py → core/activation_key.py} +2 -2
  13. adcp/types/generated_poc/core/assets/__init__.py +3 -0
  14. adcp/types/generated_poc/{audio_asset.py → core/assets/audio_asset.py} +2 -2
  15. adcp/types/generated_poc/{css_asset.py → core/assets/css_asset.py} +2 -2
  16. adcp/types/generated_poc/{daast_asset.py → core/assets/daast_asset.py} +4 -4
  17. adcp/types/generated_poc/{html_asset.py → core/assets/html_asset.py} +2 -2
  18. adcp/types/generated_poc/core/assets/image_asset.py +19 -0
  19. adcp/types/generated_poc/{javascript_asset.py → core/assets/javascript_asset.py} +3 -3
  20. adcp/types/generated_poc/{text_asset.py → core/assets/text_asset.py} +2 -2
  21. adcp/types/generated_poc/{url_asset.py → core/assets/url_asset.py} +3 -3
  22. adcp/types/generated_poc/{vast_asset.py → core/assets/vast_asset.py} +4 -4
  23. adcp/types/generated_poc/{video_asset.py → core/assets/video_asset.py} +7 -11
  24. adcp/types/generated_poc/{webhook_asset.py → core/assets/webhook_asset.py} +3 -3
  25. adcp/types/generated_poc/{brand_manifest.py → core/brand_manifest.py} +3 -3
  26. adcp/types/generated_poc/core/context.py +15 -0
  27. adcp/types/generated_poc/{creative_asset.py → core/creative_asset.py} +25 -6
  28. adcp/types/generated_poc/{creative_assignment.py → core/creative_assignment.py} +2 -2
  29. adcp/types/generated_poc/{creative_filters.py → core/creative_filters.py} +12 -3
  30. adcp/types/generated_poc/{creative_manifest.py → core/creative_manifest.py} +13 -6
  31. adcp/types/generated_poc/{creative_policy.py → core/creative_policy.py} +3 -3
  32. adcp/types/generated_poc/{delivery_metrics.py → core/delivery_metrics.py} +2 -2
  33. adcp/types/generated_poc/{deployment.py → core/deployment.py} +2 -2
  34. adcp/types/generated_poc/{destination.py → core/destination.py} +2 -2
  35. adcp/types/generated_poc/core/dimensions.py +18 -0
  36. adcp/types/generated_poc/{error.py → core/error.py} +2 -2
  37. adcp/types/generated_poc/core/ext.py +15 -0
  38. adcp/types/generated_poc/{format.py → core/format.py} +85 -54
  39. adcp/types/generated_poc/core/format_id.py +50 -0
  40. adcp/types/generated_poc/{frequency_cap.py → core/frequency_cap.py} +2 -2
  41. adcp/types/generated_poc/{measurement.py → core/measurement.py} +2 -2
  42. adcp/types/generated_poc/{media_buy.py → core/media_buy.py} +6 -3
  43. adcp/types/generated_poc/{package.py → core/package.py} +13 -6
  44. adcp/types/generated_poc/{performance_feedback.py → core/performance_feedback.py} +4 -4
  45. adcp/types/generated_poc/{placement.py → core/placement.py} +3 -3
  46. adcp/types/generated_poc/{product.py → core/product.py} +16 -6
  47. adcp/types/generated_poc/core/product_filters.py +97 -0
  48. adcp/types/generated_poc/{promoted_offerings.py → core/promoted_offerings.py} +2 -2
  49. adcp/types/generated_poc/{promoted_products.py → core/promoted_products.py} +2 -2
  50. adcp/types/generated_poc/{property.py → core/property.py} +5 -4
  51. adcp/types/generated_poc/{property_id.py → core/property_id.py} +2 -2
  52. adcp/types/generated_poc/{property_tag.py → core/property_tag.py} +2 -2
  53. adcp/types/generated_poc/{protocol_envelope.py → core/protocol_envelope.py} +3 -3
  54. adcp/types/generated_poc/{publisher_property_selector.py → core/publisher_property_selector.py} +2 -2
  55. adcp/types/generated_poc/{push_notification_config.py → core/push_notification_config.py} +3 -3
  56. adcp/types/generated_poc/{reporting_capabilities.py → core/reporting_capabilities.py} +3 -3
  57. adcp/types/generated_poc/{response.py → core/response.py} +2 -2
  58. adcp/types/generated_poc/{signal_filters.py → core/signal_filters.py} +3 -3
  59. adcp/types/generated_poc/{sub_asset.py → core/sub_asset.py} +2 -2
  60. adcp/types/generated_poc/{targeting.py → core/targeting.py} +2 -2
  61. adcp/types/generated_poc/{webhook_payload.py → core/webhook_payload.py} +4 -4
  62. adcp/types/generated_poc/creative/__init__.py +3 -0
  63. adcp/types/generated_poc/creative/list_creative_formats_request.py +88 -0
  64. adcp/types/generated_poc/creative/list_creative_formats_response.py +55 -0
  65. adcp/types/generated_poc/{preview_creative_request.py → creative/preview_creative_request.py} +13 -18
  66. adcp/types/generated_poc/{preview_creative_response.py → creative/preview_creative_response.py} +8 -14
  67. adcp/types/generated_poc/{preview_render.py → creative/preview_render.py} +2 -2
  68. adcp/types/generated_poc/enums/__init__.py +3 -0
  69. adcp/types/generated_poc/{adcp_domain.py → enums/adcp_domain.py} +2 -2
  70. adcp/types/generated_poc/{asset_content_type.py → enums/asset_content_type.py} +2 -2
  71. adcp/types/generated_poc/{auth_scheme.py → enums/auth_scheme.py} +2 -2
  72. adcp/types/generated_poc/{available_metric.py → enums/available_metric.py} +2 -2
  73. adcp/types/generated_poc/{channels.py → enums/channels.py} +2 -2
  74. adcp/types/generated_poc/{co_branding_requirement.py → enums/co_branding_requirement.py} +2 -2
  75. adcp/types/generated_poc/{creative_action.py → enums/creative_action.py} +2 -2
  76. adcp/types/generated_poc/{creative_agent_capability.py → enums/creative_agent_capability.py} +2 -2
  77. adcp/types/generated_poc/{creative_sort_field.py → enums/creative_sort_field.py} +2 -2
  78. adcp/types/generated_poc/{creative_status.py → enums/creative_status.py} +2 -2
  79. adcp/types/generated_poc/{daast_tracking_event.py → enums/daast_tracking_event.py} +2 -2
  80. adcp/types/generated_poc/{daast_version.py → enums/daast_version.py} +2 -2
  81. adcp/types/generated_poc/{delivery_type.py → enums/delivery_type.py} +2 -2
  82. adcp/types/generated_poc/{dimension_unit.py → enums/dimension_unit.py} +2 -2
  83. adcp/types/generated_poc/{feed_format.py → enums/feed_format.py} +2 -2
  84. adcp/types/generated_poc/{feedback_source.py → enums/feedback_source.py} +2 -2
  85. adcp/types/generated_poc/{format_category.py → enums/format_category.py} +2 -2
  86. adcp/types/generated_poc/enums/format_id_parameter.py +12 -0
  87. adcp/types/generated_poc/{frequency_cap_scope.py → enums/frequency_cap_scope.py} +2 -2
  88. adcp/types/generated_poc/{history_entry_type.py → enums/history_entry_type.py} +2 -2
  89. adcp/types/generated_poc/{http_method.py → enums/http_method.py} +2 -2
  90. adcp/types/generated_poc/{identifier_types.py → enums/identifier_types.py} +2 -2
  91. adcp/types/generated_poc/{javascript_module_type.py → enums/javascript_module_type.py} +2 -2
  92. adcp/types/generated_poc/{landing_page_requirement.py → enums/landing_page_requirement.py} +2 -2
  93. adcp/types/generated_poc/{markdown_flavor.py → enums/markdown_flavor.py} +2 -2
  94. adcp/types/generated_poc/{media_buy_status.py → enums/media_buy_status.py} +2 -2
  95. adcp/types/generated_poc/{metric_type.py → enums/metric_type.py} +2 -2
  96. adcp/types/generated_poc/{notification_type.py → enums/notification_type.py} +2 -2
  97. adcp/types/generated_poc/{pacing.py → enums/pacing.py} +2 -2
  98. adcp/types/generated_poc/{preview_output_format.py → enums/preview_output_format.py} +2 -2
  99. adcp/types/generated_poc/{pricing_model.py → enums/pricing_model.py} +2 -2
  100. adcp/types/generated_poc/{property_type.py → enums/property_type.py} +2 -2
  101. adcp/types/generated_poc/{publisher_identifier_types.py → enums/publisher_identifier_types.py} +2 -2
  102. adcp/types/generated_poc/{reporting_frequency.py → enums/reporting_frequency.py} +2 -2
  103. adcp/types/generated_poc/{signal_catalog_type.py → enums/signal_catalog_type.py} +2 -2
  104. adcp/types/generated_poc/{sort_direction.py → enums/sort_direction.py} +2 -2
  105. adcp/types/generated_poc/{standard_format_ids.py → enums/standard_format_ids.py} +2 -2
  106. adcp/types/generated_poc/{task_status.py → enums/task_status.py} +2 -2
  107. adcp/types/generated_poc/{task_type.py → enums/task_type.py} +2 -2
  108. adcp/types/generated_poc/{update_frequency.py → enums/update_frequency.py} +2 -2
  109. adcp/types/generated_poc/{url_asset_type.py → enums/url_asset_type.py} +2 -2
  110. adcp/types/generated_poc/{validation_mode.py → enums/validation_mode.py} +2 -2
  111. adcp/types/generated_poc/{vast_tracking_event.py → enums/vast_tracking_event.py} +2 -2
  112. adcp/types/generated_poc/{vast_version.py → enums/vast_version.py} +2 -2
  113. adcp/types/generated_poc/{webhook_response_type.py → enums/webhook_response_type.py} +2 -2
  114. adcp/types/generated_poc/{webhook_security_method.py → enums/webhook_security_method.py} +2 -2
  115. adcp/types/generated_poc/media_buy/__init__.py +3 -0
  116. adcp/types/generated_poc/{build_creative_request.py → media_buy/build_creative_request.py} +9 -11
  117. adcp/types/generated_poc/{build_creative_response.py → media_buy/build_creative_response.py} +11 -17
  118. adcp/types/generated_poc/{create_media_buy_request.py → media_buy/create_media_buy_request.py} +9 -11
  119. adcp/types/generated_poc/{create_media_buy_response.py → media_buy/create_media_buy_response.py} +11 -16
  120. adcp/types/generated_poc/{get_media_buy_delivery_request.py → media_buy/get_media_buy_delivery_request.py} +8 -10
  121. adcp/types/generated_poc/{get_media_buy_delivery_response.py → media_buy/get_media_buy_delivery_response.py} +27 -12
  122. adcp/types/generated_poc/{get_products_request.py → media_buy/get_products_request.py} +9 -11
  123. adcp/types/generated_poc/{get_products_response.py → media_buy/get_products_response.py} +9 -10
  124. adcp/types/generated_poc/{list_authorized_properties_request.py → media_buy/list_authorized_properties_request.py} +8 -9
  125. adcp/types/generated_poc/{list_authorized_properties_response.py → media_buy/list_authorized_properties_response.py} +9 -10
  126. adcp/types/generated_poc/{list_creative_formats_request.py → media_buy/list_creative_formats_request.py} +9 -10
  127. adcp/types/generated_poc/{list_creative_formats_response.py → media_buy/list_creative_formats_response.py} +10 -10
  128. adcp/types/generated_poc/{list_creatives_request.py → media_buy/list_creatives_request.py} +9 -10
  129. adcp/types/generated_poc/{list_creatives_response.py → media_buy/list_creatives_response.py} +14 -15
  130. adcp/types/generated_poc/{package_request.py → media_buy/package_request.py} +7 -5
  131. adcp/types/generated_poc/{provide_performance_feedback_request.py → media_buy/provide_performance_feedback_request.py} +11 -17
  132. adcp/types/generated_poc/{provide_performance_feedback_response.py → media_buy/provide_performance_feedback_response.py} +10 -16
  133. adcp/types/generated_poc/{sync_creatives_request.py → media_buy/sync_creatives_request.py} +14 -15
  134. adcp/types/generated_poc/{sync_creatives_response.py → media_buy/sync_creatives_response.py} +11 -16
  135. adcp/types/generated_poc/{update_media_buy_request.py → media_buy/update_media_buy_request.py} +63 -28
  136. adcp/types/generated_poc/{update_media_buy_response.py → media_buy/update_media_buy_response.py} +11 -16
  137. adcp/types/generated_poc/pricing_options/__init__.py +3 -0
  138. adcp/types/generated_poc/{cpc_option.py → pricing_options/cpc_option.py} +2 -2
  139. adcp/types/generated_poc/{cpcv_option.py → pricing_options/cpcv_option.py} +2 -2
  140. adcp/types/generated_poc/{cpm_auction_option.py → pricing_options/cpm_auction_option.py} +2 -2
  141. adcp/types/generated_poc/{cpm_fixed_option.py → pricing_options/cpm_fixed_option.py} +2 -2
  142. adcp/types/generated_poc/{cpp_option.py → pricing_options/cpp_option.py} +2 -2
  143. adcp/types/generated_poc/{cpv_option.py → pricing_options/cpv_option.py} +2 -2
  144. adcp/types/generated_poc/{flat_rate_option.py → pricing_options/flat_rate_option.py} +2 -2
  145. adcp/types/generated_poc/{vcpm_auction_option.py → pricing_options/vcpm_auction_option.py} +2 -2
  146. adcp/types/generated_poc/{vcpm_fixed_option.py → pricing_options/vcpm_fixed_option.py} +2 -2
  147. adcp/types/generated_poc/protocols/__init__.py +3 -0
  148. adcp/types/generated_poc/protocols/adcp_extension.py +37 -0
  149. adcp/types/generated_poc/signals/__init__.py +3 -0
  150. adcp/types/generated_poc/{activate_signal_request.py → signals/activate_signal_request.py} +8 -10
  151. adcp/types/generated_poc/{activate_signal_response.py → signals/activate_signal_response.py} +10 -16
  152. adcp/types/generated_poc/{get_signals_request.py → signals/get_signals_request.py} +9 -10
  153. adcp/types/generated_poc/{get_signals_response.py → signals/get_signals_response.py} +9 -10
  154. adcp/utils/preview_cache.py +15 -3
  155. {adcp-2.11.1.dist-info → adcp-2.12.1.dist-info}/METADATA +1 -1
  156. adcp-2.12.1.dist-info/RECORD +176 -0
  157. adcp/types/generated_poc/format_id.py +0 -29
  158. adcp/types/generated_poc/image_asset.py +0 -23
  159. adcp/types/generated_poc/markdown_asset.py +0 -39
  160. adcp/types/generated_poc/package_status.py +0 -14
  161. adcp/types/generated_poc/product_filters.py +0 -36
  162. adcp/types/generated_poc/tasks_get_request.py +0 -29
  163. adcp/types/generated_poc/tasks_get_response.py +0 -112
  164. adcp/types/generated_poc/tasks_list_request.py +0 -115
  165. adcp/types/generated_poc/tasks_list_response.py +0 -122
  166. adcp-2.11.1.dist-info/RECORD +0 -166
  167. {adcp-2.11.1.dist-info → adcp-2.12.1.dist-info}/WHEEL +0 -0
  168. {adcp-2.11.1.dist-info → adcp-2.12.1.dist-info}/entry_points.txt +0 -0
  169. {adcp-2.11.1.dist-info → adcp-2.12.1.dist-info}/licenses/LICENSE +0 -0
  170. {adcp-2.11.1.dist-info → adcp-2.12.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: creative-filters.json
3
- # timestamp: 2025-11-21T12:49:05+00:00
2
+ # filename: core/creative_filters.json
3
+ # timestamp: 2025-11-22T16:02:47+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9,7 +9,7 @@ from typing import Annotated
9
9
  from adcp.types.base import AdCPBaseModel
10
10
  from pydantic import AwareDatetime, ConfigDict, Field
11
11
 
12
- from . import creative_status
12
+ from ..enums import creative_status
13
13
 
14
14
 
15
15
  class CreativeFilters(AdCPBaseModel):
@@ -22,6 +22,12 @@ class CreativeFilters(AdCPBaseModel):
22
22
  assigned_to_packages: Annotated[
23
23
  list[str] | None, Field(description='Filter creatives assigned to any of these packages')
24
24
  ] = None
25
+ buyer_refs: Annotated[
26
+ list[str] | None,
27
+ Field(
28
+ description='Filter creatives assigned to media buys with any of these buyer references'
29
+ ),
30
+ ] = None
25
31
  created_after: Annotated[
26
32
  AwareDatetime | None,
27
33
  Field(description='Filter creatives created after this date (ISO 8601)'),
@@ -43,6 +49,9 @@ class CreativeFilters(AdCPBaseModel):
43
49
  has_performance_data: Annotated[
44
50
  bool | None, Field(description='Filter creatives that have performance data when true')
45
51
  ] = None
52
+ media_buy_ids: Annotated[
53
+ list[str] | None, Field(description='Filter creatives assigned to any of these media buys')
54
+ ] = None
46
55
  name_contains: Annotated[
47
56
  str | None,
48
57
  Field(description='Filter by creative names containing this text (case-insensitive)'),
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: creative-manifest.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/creative_manifest.json
3
+ # timestamp: 2025-11-22T19:54:03+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9,13 +9,16 @@ from typing import Annotated
9
9
  from adcp.types.base import AdCPBaseModel
10
10
  from pydantic import ConfigDict, Field
11
11
 
12
- from . import audio_asset, css_asset, daast_asset
12
+ from . import ext as ext_1
13
13
  from . import format_id as format_id_1
14
- from . import (
14
+ from . import promoted_offerings
15
+ from .assets import (
16
+ audio_asset,
17
+ css_asset,
18
+ daast_asset,
15
19
  html_asset,
16
20
  image_asset,
17
21
  javascript_asset,
18
- promoted_offerings,
19
22
  text_asset,
20
23
  url_asset,
21
24
  vast_asset,
@@ -50,8 +53,12 @@ class CreativeManifest(AdCPBaseModel):
50
53
  description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets_required array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.\n\nIMPORTANT: Creative manifest validation MUST be performed in the context of the format specification. The format defines what type each asset_id should be, which eliminates any validation ambiguity."
51
54
  ),
52
55
  ]
56
+ ext: ext_1.ExtensionObject | None = None
53
57
  format_id: Annotated[
54
- format_id_1.FormatId, Field(description='Format identifier this manifest is for')
58
+ format_id_1.FormatId,
59
+ Field(
60
+ description="Format identifier this manifest is for. Can be a template format (id only) or a deterministic format (id + dimensions/duration). For dimension-specific creatives, include width/height/unit in the format_id to create a unique identifier (e.g., {id: 'display_static', width: 300, height: 250, unit: 'px'})."
61
+ ),
55
62
  ]
56
63
  promoted_offering: Annotated[
57
64
  str | None,
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: creative-policy.json
3
- # timestamp: 2025-11-21T12:49:05+00:00
2
+ # filename: core/creative_policy.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9,7 +9,7 @@ from typing import Annotated
9
9
  from adcp.types.base import AdCPBaseModel
10
10
  from pydantic import ConfigDict, Field
11
11
 
12
- from . import co_branding_requirement, landing_page_requirement
12
+ from ..enums import co_branding_requirement, landing_page_requirement
13
13
 
14
14
 
15
15
  class CreativePolicy(AdCPBaseModel):
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: delivery-metrics.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/delivery_metrics.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: deployment.json
3
- # timestamp: 2025-11-20T20:44:40+00:00
2
+ # filename: core/deployment.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: destination.json
3
- # timestamp: 2025-11-20T20:44:40+00:00
2
+ # filename: core/destination.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -0,0 +1,18 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/dimensions.json
3
+ # timestamp: 2025-11-22T19:16:02+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 ConfigDict, Field
11
+
12
+
13
+ class Dimensions(AdCPBaseModel):
14
+ model_config = ConfigDict(
15
+ extra='forbid',
16
+ )
17
+ height: Annotated[int, Field(description='Height in pixels', ge=1)]
18
+ width: Annotated[int, Field(description='Width in pixels', ge=1)]
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: error.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/error.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -0,0 +1,15 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/ext.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from adcp.types.base import AdCPBaseModel
8
+ from pydantic import ConfigDict
9
+
10
+
11
+ class ExtensionObject(AdCPBaseModel):
12
+ pass
13
+ model_config = ConfigDict(
14
+ extra='allow',
15
+ )
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: format.json
3
- # timestamp: 2025-11-21T12:49:05+00:00
2
+ # filename: core/format.json
3
+ # timestamp: 2025-11-22T19:54:03+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9,7 +9,7 @@ from typing import Annotated, Any, Literal
9
9
  from adcp.types.base import AdCPBaseModel
10
10
  from pydantic import AnyUrl, ConfigDict, Field
11
11
 
12
- from . import asset_content_type, dimension_unit, format_category
12
+ from ..enums import asset_content_type, format_category, format_id_parameter
13
13
  from . import format_id as format_id_1
14
14
 
15
15
 
@@ -35,7 +35,7 @@ class AssetsRequired(AdCPBaseModel):
35
35
  requirements: Annotated[
36
36
  dict[str, Any] | None,
37
37
  Field(
38
- description='Technical requirements for this asset (dimensions, file size, duration, etc.)'
38
+ description='Technical requirements for this asset (dimensions, file size, duration, etc.). For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms).'
39
39
  ),
40
40
  ] = None
41
41
 
@@ -53,7 +53,10 @@ class Asset(AdCPBaseModel):
53
53
  bool | None, Field(description='Whether this asset is required in each repetition')
54
54
  ] = None
55
55
  requirements: Annotated[
56
- dict[str, Any] | None, Field(description='Technical requirements for this asset')
56
+ dict[str, Any] | None,
57
+ Field(
58
+ description='Technical requirements for this asset. For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms).'
59
+ ),
57
60
  ] = None
58
61
 
59
62
 
@@ -70,40 +73,6 @@ class AssetsRequired1(AdCPBaseModel):
70
73
  min_count: Annotated[int, Field(description='Minimum number of repetitions required', ge=1)]
71
74
 
72
75
 
73
- class FormatCard(AdCPBaseModel):
74
- model_config = ConfigDict(
75
- extra='forbid',
76
- )
77
- format_id: Annotated[
78
- format_id_1.FormatId,
79
- Field(
80
- description='Creative format defining the card layout (typically format_card_standard)'
81
- ),
82
- ]
83
- manifest: Annotated[
84
- dict[str, Any],
85
- Field(description='Asset manifest for rendering the card, structure defined by the format'),
86
- ]
87
-
88
-
89
- class FormatCardDetailed(AdCPBaseModel):
90
- model_config = ConfigDict(
91
- extra='forbid',
92
- )
93
- format_id: Annotated[
94
- format_id_1.FormatId,
95
- Field(
96
- description='Creative format defining the detailed card layout (typically format_card_detailed)'
97
- ),
98
- ]
99
- manifest: Annotated[
100
- dict[str, Any],
101
- Field(
102
- description='Asset manifest for rendering the detailed card, structure defined by the format'
103
- ),
104
- ]
105
-
106
-
107
76
  class Responsive(AdCPBaseModel):
108
77
  height: bool
109
78
  width: bool
@@ -117,34 +86,56 @@ class Dimensions(AdCPBaseModel):
117
86
  pattern='^\\d+:\\d+$',
118
87
  ),
119
88
  ] = None
120
- height: Annotated[
121
- float | None, Field(description='Fixed height in specified units', ge=0.0)
122
- ] = None
89
+ height: Annotated[int | None, Field(description='Fixed height in pixels', ge=1)] = None
123
90
  max_height: Annotated[
124
- float | None, Field(description='Maximum height for responsive renders', ge=0.0)
91
+ int | None, Field(description='Maximum height in pixels for responsive renders', ge=1)
125
92
  ] = None
126
93
  max_width: Annotated[
127
- float | None, Field(description='Maximum width for responsive renders', ge=0.0)
94
+ int | None, Field(description='Maximum width in pixels for responsive renders', ge=1)
128
95
  ] = None
129
96
  min_height: Annotated[
130
- float | None, Field(description='Minimum height for responsive renders', ge=0.0)
97
+ int | None, Field(description='Minimum height in pixels for responsive renders', ge=1)
131
98
  ] = None
132
99
  min_width: Annotated[
133
- float | None, Field(description='Minimum width for responsive renders', ge=0.0)
100
+ int | None, Field(description='Minimum width in pixels for responsive renders', ge=1)
134
101
  ] = None
135
102
  responsive: Annotated[
136
103
  Responsive | None, Field(description='Indicates which dimensions are responsive/fluid')
137
104
  ] = None
138
- unit: Annotated[
139
- dimension_unit.DimensionUnit, Field(description='Unit of measurement for dimensions')
105
+ width: Annotated[int | None, Field(description='Fixed width in pixels', ge=1)] = None
106
+
107
+
108
+ class Renders(AdCPBaseModel):
109
+ dimensions: Annotated[
110
+ Dimensions, Field(description='Dimensions for this rendered piece (in pixels)')
111
+ ]
112
+ parameters_from_format_id: Annotated[
113
+ bool | None,
114
+ Field(
115
+ description='When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly.'
116
+ ),
117
+ ] = None
118
+ role: Annotated[
119
+ str,
120
+ Field(
121
+ description="Semantic role of this rendered piece (e.g., 'primary', 'companion', 'mobile_variant')"
122
+ ),
140
123
  ]
141
- width: Annotated[float | None, Field(description='Fixed width in specified units', ge=0.0)] = (
142
- None
143
- )
144
124
 
145
125
 
146
- class Render(AdCPBaseModel):
147
- dimensions: Annotated[Dimensions, Field(description='Dimensions for this rendered piece')]
126
+ Dimensions2 = Dimensions
127
+
128
+
129
+ class Renders1(AdCPBaseModel):
130
+ dimensions: Annotated[
131
+ Dimensions2 | None, Field(description='Dimensions for this rendered piece (in pixels)')
132
+ ] = None
133
+ parameters_from_format_id: Annotated[
134
+ Literal[True],
135
+ Field(
136
+ description='When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly.'
137
+ ),
138
+ ]
148
139
  role: Annotated[
149
140
  str,
150
141
  Field(
@@ -153,10 +144,50 @@ class Render(AdCPBaseModel):
153
144
  ]
154
145
 
155
146
 
147
+ class FormatCard(AdCPBaseModel):
148
+ model_config = ConfigDict(
149
+ extra='forbid',
150
+ )
151
+ format_id: Annotated[
152
+ format_id_1.FormatId,
153
+ Field(
154
+ description='Creative format defining the card layout (typically format_card_standard)'
155
+ ),
156
+ ]
157
+ manifest: Annotated[
158
+ dict[str, Any],
159
+ Field(description='Asset manifest for rendering the card, structure defined by the format'),
160
+ ]
161
+
162
+
163
+ class FormatCardDetailed(AdCPBaseModel):
164
+ model_config = ConfigDict(
165
+ extra='forbid',
166
+ )
167
+ format_id: Annotated[
168
+ format_id_1.FormatId,
169
+ Field(
170
+ description='Creative format defining the detailed card layout (typically format_card_detailed)'
171
+ ),
172
+ ]
173
+ manifest: Annotated[
174
+ dict[str, Any],
175
+ Field(
176
+ description='Asset manifest for rendering the detailed card, structure defined by the format'
177
+ ),
178
+ ]
179
+
180
+
156
181
  class Format(AdCPBaseModel):
157
182
  model_config = ConfigDict(
158
183
  extra='forbid',
159
184
  )
185
+ accepts_parameters: Annotated[
186
+ list[format_id_parameter.FormatIdParameter] | None,
187
+ Field(
188
+ description='List of parameters this format accepts in format_id. Template formats define which parameters (dimensions, duration, etc.) can be specified when instantiating the format. Empty or omitted means this is a concrete format with fixed parameters.'
189
+ ),
190
+ ] = None
160
191
  assets_required: Annotated[
161
192
  list[AssetsRequired | AssetsRequired1] | None,
162
193
  Field(
@@ -209,7 +240,7 @@ class Format(AdCPBaseModel):
209
240
  ),
210
241
  ] = None
211
242
  renders: Annotated[
212
- list[Render] | None,
243
+ list[Renders | Renders1] | None,
213
244
  Field(
214
245
  description='Specification of rendered pieces for this format. Most formats produce a single render. Companion ad formats (video + banner), adaptive formats, and multi-placement formats produce multiple renders. Each render specifies its role and dimensions.',
215
246
  min_length=1,
@@ -0,0 +1,50 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/format_id.json
3
+ # timestamp: 2025-11-22T19:54:03+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 AnyUrl, ConfigDict, Field
11
+
12
+
13
+ class FormatId(AdCPBaseModel):
14
+ model_config = ConfigDict(
15
+ extra='forbid',
16
+ )
17
+ agent_url: Annotated[
18
+ AnyUrl,
19
+ Field(
20
+ description="URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)"
21
+ ),
22
+ ]
23
+ duration_ms: Annotated[
24
+ float | None,
25
+ Field(
26
+ description='Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters.',
27
+ ge=1.0,
28
+ ),
29
+ ] = None
30
+ height: Annotated[
31
+ int | None,
32
+ Field(
33
+ description='Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.',
34
+ ge=1,
35
+ ),
36
+ ] = None
37
+ id: Annotated[
38
+ str,
39
+ Field(
40
+ description="Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant.",
41
+ pattern='^[a-zA-Z0-9_-]+$',
42
+ ),
43
+ ]
44
+ width: Annotated[
45
+ int | None,
46
+ Field(
47
+ description='Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.',
48
+ ge=1,
49
+ ),
50
+ ] = None
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: frequency-cap.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/frequency_cap.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: measurement.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/measurement.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: media-buy.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/media_buy.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9,7 +9,9 @@ from typing import Annotated
9
9
  from adcp.types.base import AdCPBaseModel
10
10
  from pydantic import AwareDatetime, ConfigDict, Field
11
11
 
12
- from . import media_buy_status, package
12
+ from ..enums import media_buy_status
13
+ from . import ext as ext_1
14
+ from . import package
13
15
 
14
16
 
15
17
  class MediaBuy(AdCPBaseModel):
@@ -23,6 +25,7 @@ class MediaBuy(AdCPBaseModel):
23
25
  creative_deadline: Annotated[
24
26
  AwareDatetime | None, Field(description='ISO 8601 timestamp for creative upload deadline')
25
27
  ] = None
28
+ ext: ext_1.ExtensionObject | None = None
26
29
  media_buy_id: Annotated[
27
30
  str, Field(description="Publisher's unique identifier for the media buy")
28
31
  ]
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: package.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/package.json
3
+ # timestamp: 2025-11-22T19:54:03+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9,9 +9,10 @@ from typing import Annotated
9
9
  from adcp.types.base import AdCPBaseModel
10
10
  from pydantic import ConfigDict, Field
11
11
 
12
- from . import creative_assignment, format_id
13
- from . import pacing as pacing_1
14
- from . import package_status, targeting
12
+ from ..enums import pacing as pacing_1
13
+ from . import creative_assignment
14
+ from . import ext as ext_1
15
+ from . import format_id, targeting
15
16
 
16
17
 
17
18
  class Package(AdCPBaseModel):
@@ -39,6 +40,7 @@ class Package(AdCPBaseModel):
39
40
  list[creative_assignment.CreativeAssignment] | None,
40
41
  Field(description='Creative assets assigned to this package'),
41
42
  ] = None
43
+ ext: ext_1.ExtensionObject | None = None
42
44
  format_ids_to_provide: Annotated[
43
45
  list[format_id.FormatId] | None,
44
46
  Field(description='Format IDs that creative assets will be provided for this package'),
@@ -48,6 +50,12 @@ class Package(AdCPBaseModel):
48
50
  ] = None
49
51
  pacing: pacing_1.Pacing | None = None
50
52
  package_id: Annotated[str, Field(description="Publisher's unique identifier for the package")]
53
+ paused: Annotated[
54
+ bool | None,
55
+ Field(
56
+ description='Whether this package is paused by the buyer. Paused packages do not deliver impressions. Defaults to false.'
57
+ ),
58
+ ] = False
51
59
  pricing_option_id: Annotated[
52
60
  str | None,
53
61
  Field(
@@ -57,5 +65,4 @@ class Package(AdCPBaseModel):
57
65
  product_id: Annotated[
58
66
  str | None, Field(description='ID of the product this package is based on')
59
67
  ] = None
60
- status: package_status.PackageStatus
61
68
  targeting_overlay: targeting.TargetingOverlay | None = None
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: performance-feedback.json
3
- # timestamp: 2025-11-21T12:49:05+00:00
2
+ # filename: core/performance_feedback.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -10,8 +10,8 @@ from typing import Annotated
10
10
  from adcp.types.base import AdCPBaseModel
11
11
  from pydantic import AwareDatetime, ConfigDict, Field
12
12
 
13
- from . import feedback_source as feedback_source_1
14
- from . import metric_type as metric_type_1
13
+ from ..enums import feedback_source as feedback_source_1
14
+ from ..enums import metric_type as metric_type_1
15
15
 
16
16
 
17
17
  class MeasurementPeriod(AdCPBaseModel):
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: placement.json
3
- # timestamp: 2025-11-18T03:35:10+00:00
2
+ # filename: core/placement.json
3
+ # timestamp: 2025-11-22T19:54:03+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -22,7 +22,7 @@ class Placement(AdCPBaseModel):
22
22
  format_ids: Annotated[
23
23
  list[format_id.FormatId] | None,
24
24
  Field(
25
- description="Format IDs supported by this specific placement (subset of product's formats)",
25
+ description='Format IDs supported by this specific placement. Can include: (1) concrete format_ids (fixed dimensions), (2) template format_ids without parameters (accepts any dimensions/duration), or (3) parameterized format_ids (specific dimension/duration constraints).',
26
26
  min_length=1,
27
27
  ),
28
28
  ] = None
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
- # filename: product.json
3
- # timestamp: 2025-11-19T02:02:39+00:00
2
+ # filename: core/product.json
3
+ # timestamp: 2025-11-22T19:54:03+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9,15 +9,24 @@ from typing import Annotated, Any
9
9
  from adcp.types.base import AdCPBaseModel
10
10
  from pydantic import AwareDatetime, ConfigDict, Field
11
11
 
12
- from . import cpc_option, cpcv_option, cpm_auction_option, cpm_fixed_option, cpp_option, cpv_option
12
+ from ..enums import delivery_type as delivery_type_1
13
+ from ..pricing_options import (
14
+ cpc_option,
15
+ cpcv_option,
16
+ cpm_auction_option,
17
+ cpm_fixed_option,
18
+ cpp_option,
19
+ cpv_option,
20
+ flat_rate_option,
21
+ vcpm_auction_option,
22
+ vcpm_fixed_option,
23
+ )
13
24
  from . import creative_policy as creative_policy_1
14
- from . import delivery_type as delivery_type_1
15
- from . import flat_rate_option
25
+ from . import ext as ext_1
16
26
  from . import format_id as format_id_1
17
27
  from . import measurement as measurement_1
18
28
  from . import placement, publisher_property_selector
19
29
  from . import reporting_capabilities as reporting_capabilities_1
20
- from . import vcpm_auction_option, vcpm_fixed_option
21
30
 
22
31
 
23
32
  class DeliveryMeasurement(AdCPBaseModel):
@@ -97,6 +106,7 @@ class Product(AdCPBaseModel):
97
106
  expires_at: Annotated[
98
107
  AwareDatetime | None, Field(description='Expiration timestamp for custom products')
99
108
  ] = None
109
+ ext: ext_1.ExtensionObject | None = None
100
110
  format_ids: Annotated[
101
111
  list[format_id_1.FormatId],
102
112
  Field(