adcp 2.19.0__py3-none-any.whl → 3.1.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.
- adcp/ADCP_VERSION +1 -1
- adcp/__init__.py +14 -14
- adcp/__main__.py +94 -51
- adcp/adagents.py +91 -19
- adcp/client.py +865 -0
- adcp/protocols/a2a.py +84 -0
- adcp/protocols/base.py +101 -0
- adcp/protocols/mcp.py +84 -0
- adcp/server/__init__.py +49 -0
- adcp/server/base.py +368 -0
- adcp/server/content_standards.py +561 -0
- adcp/server/governance.py +491 -0
- adcp/server/mcp_tools.py +471 -0
- adcp/server/proposal.py +334 -0
- adcp/server/sponsored_intelligence.py +444 -0
- adcp/types/__init__.py +115 -23
- adcp/types/_ergonomic.py +35 -14
- adcp/types/_generated.py +346 -52
- adcp/types/aliases.py +68 -20
- adcp/types/base.py +1 -1
- adcp/types/generated_poc/adagents.py +196 -189
- adcp/types/generated_poc/content_standards/__init__.py +3 -0
- adcp/types/generated_poc/content_standards/artifact.py +208 -0
- adcp/types/generated_poc/content_standards/artifact_webhook_payload.py +64 -0
- adcp/types/generated_poc/content_standards/calibrate_content_request.py +17 -0
- adcp/types/generated_poc/content_standards/calibrate_content_response.py +74 -0
- adcp/types/generated_poc/content_standards/content_standards.py +66 -0
- adcp/types/generated_poc/content_standards/create_content_standards_request.py +97 -0
- adcp/types/generated_poc/content_standards/create_content_standards_response.py +52 -0
- adcp/types/generated_poc/content_standards/get_content_standards_request.py +21 -0
- adcp/types/generated_poc/content_standards/get_content_standards_response.py +43 -0
- adcp/types/generated_poc/content_standards/get_media_buy_artifacts_request.py +64 -0
- adcp/types/generated_poc/content_standards/get_media_buy_artifacts_response.py +117 -0
- adcp/types/generated_poc/content_standards/list_content_standards_request.py +31 -0
- adcp/types/generated_poc/content_standards/list_content_standards_response.py +48 -0
- adcp/types/generated_poc/content_standards/update_content_standards_request.py +101 -0
- adcp/types/generated_poc/content_standards/update_content_standards_response.py +34 -0
- adcp/types/generated_poc/content_standards/validate_content_delivery_request.py +59 -0
- adcp/types/generated_poc/content_standards/validate_content_delivery_response.py +85 -0
- adcp/types/generated_poc/core/activation_key.py +9 -9
- adcp/types/generated_poc/core/assets/audio_asset.py +6 -6
- adcp/types/generated_poc/core/assets/css_asset.py +3 -3
- adcp/types/generated_poc/core/assets/daast_asset.py +19 -19
- adcp/types/generated_poc/core/assets/html_asset.py +3 -3
- adcp/types/generated_poc/core/assets/image_asset.py +7 -7
- adcp/types/generated_poc/core/assets/javascript_asset.py +4 -4
- adcp/types/generated_poc/core/assets/text_asset.py +3 -3
- adcp/types/generated_poc/core/assets/url_asset.py +4 -4
- adcp/types/generated_poc/core/assets/vast_asset.py +19 -19
- adcp/types/generated_poc/core/assets/video_asset.py +8 -8
- adcp/types/generated_poc/core/assets/webhook_asset.py +10 -10
- adcp/types/generated_poc/core/async_response_data.py +3 -3
- adcp/types/generated_poc/core/brand_manifest.py +122 -59
- adcp/types/generated_poc/core/brand_manifest_ref.py +10 -10
- adcp/types/generated_poc/core/context.py +2 -2
- adcp/types/generated_poc/core/creative_asset.py +20 -19
- adcp/types/generated_poc/core/creative_assignment.py +4 -4
- adcp/types/generated_poc/core/creative_filters.py +18 -28
- adcp/types/generated_poc/core/creative_manifest.py +3 -3
- adcp/types/generated_poc/core/creative_policy.py +5 -5
- adcp/types/generated_poc/core/delivery_metrics.py +33 -33
- adcp/types/generated_poc/core/deployment.py +21 -21
- adcp/types/generated_poc/core/destination.py +12 -12
- adcp/types/generated_poc/core/error.py +7 -7
- adcp/types/generated_poc/core/ext.py +2 -2
- adcp/types/generated_poc/core/format.py +66 -66
- adcp/types/generated_poc/core/format_id.py +6 -6
- adcp/types/generated_poc/core/frequency_cap.py +3 -3
- adcp/types/generated_poc/core/identifier.py +3 -3
- adcp/types/generated_poc/core/mcp_webhook_payload.py +11 -11
- adcp/types/generated_poc/core/measurement.py +9 -9
- adcp/types/generated_poc/core/media_buy.py +8 -8
- adcp/types/generated_poc/core/media_buy_features.py +29 -0
- adcp/types/generated_poc/core/offering.py +80 -0
- adcp/types/generated_poc/core/package.py +9 -9
- adcp/types/generated_poc/core/performance_feedback.py +19 -19
- adcp/types/generated_poc/core/placement.py +5 -5
- adcp/types/generated_poc/core/pricing_option.py +9 -15
- adcp/types/generated_poc/core/product.py +21 -21
- adcp/types/generated_poc/core/product_allocation.py +48 -0
- adcp/types/generated_poc/core/product_filters.py +89 -24
- adcp/types/generated_poc/core/promoted_offerings.py +29 -38
- adcp/types/generated_poc/core/promoted_products.py +3 -3
- adcp/types/generated_poc/core/property.py +10 -10
- adcp/types/generated_poc/core/property_id.py +5 -5
- adcp/types/generated_poc/core/property_list_ref.py +5 -5
- adcp/types/generated_poc/core/property_tag.py +5 -5
- adcp/types/generated_poc/core/proposal.py +64 -0
- adcp/types/generated_poc/core/protocol_envelope.py +9 -9
- adcp/types/generated_poc/core/publisher_property_selector.py +14 -14
- adcp/types/generated_poc/core/push_notification_config.py +6 -6
- adcp/types/generated_poc/core/reporting_capabilities.py +9 -9
- adcp/types/generated_poc/core/reporting_webhook.py +70 -0
- adcp/types/generated_poc/core/response.py +5 -5
- adcp/types/generated_poc/core/signal_filters.py +6 -6
- adcp/types/generated_poc/core/start_timing.py +4 -4
- adcp/types/generated_poc/core/sub_asset.py +15 -15
- adcp/types/generated_poc/core/targeting.py +59 -18
- adcp/types/generated_poc/creative/list_creative_formats_request.py +21 -21
- adcp/types/generated_poc/creative/list_creative_formats_response.py +6 -6
- adcp/types/generated_poc/creative/preview_creative_request.py +25 -25
- adcp/types/generated_poc/creative/preview_creative_response.py +29 -29
- adcp/types/generated_poc/creative/preview_render.py +26 -26
- adcp/types/generated_poc/enums/adcp_domain.py +5 -5
- adcp/types/generated_poc/enums/asset_content_type.py +14 -14
- adcp/types/generated_poc/enums/auth_scheme.py +3 -3
- adcp/types/generated_poc/enums/available_metric.py +10 -10
- adcp/types/generated_poc/enums/channels.py +21 -11
- adcp/types/generated_poc/enums/co_branding_requirement.py +4 -4
- adcp/types/generated_poc/enums/creative_action.py +6 -6
- adcp/types/generated_poc/enums/creative_agent_capability.py +5 -5
- adcp/types/generated_poc/enums/creative_sort_field.py +7 -7
- adcp/types/generated_poc/enums/creative_status.py +6 -5
- adcp/types/generated_poc/enums/daast_tracking_event.py +12 -12
- adcp/types/generated_poc/enums/daast_version.py +3 -3
- adcp/types/generated_poc/enums/delivery_type.py +3 -3
- adcp/types/generated_poc/enums/dimension_unit.py +5 -5
- adcp/types/generated_poc/enums/feed_format.py +4 -4
- adcp/types/generated_poc/enums/feedback_source.py +5 -5
- adcp/types/generated_poc/enums/format_category.py +8 -8
- adcp/types/generated_poc/enums/format_id_parameter.py +3 -3
- adcp/types/generated_poc/enums/frequency_cap_scope.py +4 -4
- adcp/types/generated_poc/enums/geo_level.py +14 -0
- adcp/types/generated_poc/enums/history_entry_type.py +3 -3
- adcp/types/generated_poc/enums/http_method.py +3 -3
- adcp/types/generated_poc/enums/identifier_types.py +20 -20
- adcp/types/generated_poc/enums/javascript_module_type.py +4 -4
- adcp/types/generated_poc/enums/landing_page_requirement.py +4 -4
- adcp/types/generated_poc/enums/markdown_flavor.py +3 -3
- adcp/types/generated_poc/enums/media_buy_status.py +5 -5
- adcp/types/generated_poc/enums/metric_type.py +9 -9
- adcp/types/generated_poc/enums/metro_system.py +15 -0
- adcp/types/generated_poc/enums/notification_type.py +5 -5
- adcp/types/generated_poc/enums/pacing.py +4 -4
- adcp/types/generated_poc/enums/postal_system.py +19 -0
- adcp/types/generated_poc/enums/preview_output_format.py +3 -3
- adcp/types/generated_poc/enums/pricing_model.py +8 -8
- adcp/types/generated_poc/enums/property_type.py +9 -8
- adcp/types/generated_poc/enums/publisher_identifier_types.py +6 -6
- adcp/types/generated_poc/enums/reporting_frequency.py +4 -4
- adcp/types/generated_poc/enums/signal_catalog_type.py +4 -4
- adcp/types/generated_poc/enums/sort_direction.py +3 -3
- adcp/types/generated_poc/enums/task_status.py +10 -10
- adcp/types/generated_poc/enums/task_type.py +12 -12
- adcp/types/generated_poc/enums/update_frequency.py +5 -5
- adcp/types/generated_poc/enums/url_asset_type.py +4 -4
- adcp/types/generated_poc/enums/validation_mode.py +3 -3
- adcp/types/generated_poc/enums/vast_tracking_event.py +17 -17
- adcp/types/generated_poc/enums/vast_version.py +6 -6
- adcp/types/generated_poc/enums/webhook_response_type.py +5 -5
- adcp/types/generated_poc/enums/webhook_security_method.py +4 -4
- adcp/types/generated_poc/extensions/extension_meta.py +20 -12
- adcp/types/generated_poc/media_buy/build_creative_request.py +5 -5
- adcp/types/generated_poc/media_buy/build_creative_response.py +7 -7
- adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py +6 -6
- adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py +2 -2
- adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py +6 -6
- adcp/types/generated_poc/media_buy/create_media_buy_request.py +65 -37
- adcp/types/generated_poc/media_buy/create_media_buy_response.py +8 -8
- adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py +9 -9
- adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py +52 -52
- adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py +7 -7
- adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py +3 -3
- adcp/types/generated_poc/media_buy/get_products_async_response_working.py +5 -5
- adcp/types/generated_poc/media_buy/get_products_request.py +14 -5
- adcp/types/generated_poc/media_buy/get_products_response.py +12 -6
- adcp/types/generated_poc/media_buy/list_authorized_properties_request.py +4 -4
- adcp/types/generated_poc/media_buy/list_authorized_properties_response.py +9 -9
- adcp/types/generated_poc/media_buy/list_creative_formats_request.py +10 -10
- adcp/types/generated_poc/media_buy/list_creative_formats_response.py +6 -6
- adcp/types/generated_poc/media_buy/list_creatives_request.py +24 -24
- adcp/types/generated_poc/media_buy/list_creatives_response.py +54 -57
- adcp/types/generated_poc/media_buy/package_request.py +12 -12
- adcp/types/generated_poc/media_buy/package_update.py +119 -0
- adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py +20 -20
- adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py +7 -7
- adcp/types/generated_poc/media_buy/sync_creatives_async_response_input_required.py +6 -6
- adcp/types/generated_poc/media_buy/sync_creatives_async_response_submitted.py +2 -2
- adcp/types/generated_poc/media_buy/sync_creatives_async_response_working.py +8 -8
- adcp/types/generated_poc/media_buy/sync_creatives_request.py +8 -8
- adcp/types/generated_poc/media_buy/sync_creatives_response.py +16 -16
- adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py +5 -5
- adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py +2 -2
- adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py +6 -6
- adcp/types/generated_poc/media_buy/update_media_buy_request.py +28 -124
- adcp/types/generated_poc/media_buy/update_media_buy_response.py +8 -8
- adcp/types/generated_poc/pricing_options/cpc_option.py +40 -15
- adcp/types/generated_poc/pricing_options/cpcv_option.py +41 -16
- adcp/types/generated_poc/pricing_options/cpm_option.py +62 -0
- adcp/types/generated_poc/pricing_options/cpp_option.py +46 -23
- adcp/types/generated_poc/pricing_options/cpv_option.py +45 -26
- adcp/types/generated_poc/pricing_options/flat_rate_option.py +53 -47
- adcp/types/generated_poc/pricing_options/vcpm_option.py +70 -0
- adcp/types/generated_poc/property/base_property_source.py +16 -16
- adcp/types/generated_poc/property/create_property_list_request.py +5 -5
- adcp/types/generated_poc/property/create_property_list_response.py +4 -4
- adcp/types/generated_poc/property/delete_property_list_request.py +3 -3
- adcp/types/generated_poc/property/delete_property_list_response.py +4 -4
- adcp/types/generated_poc/property/feature_requirement.py +8 -8
- adcp/types/generated_poc/property/get_property_list_request.py +6 -6
- adcp/types/generated_poc/property/get_property_list_response.py +12 -12
- adcp/types/generated_poc/property/list_property_lists_request.py +6 -6
- adcp/types/generated_poc/property/list_property_lists_response.py +9 -9
- adcp/types/generated_poc/property/property_error.py +11 -11
- adcp/types/generated_poc/property/property_feature.py +5 -5
- adcp/types/generated_poc/property/property_feature_definition.py +19 -19
- adcp/types/generated_poc/property/property_list.py +12 -12
- adcp/types/generated_poc/property/property_list_changed_webhook.py +12 -12
- adcp/types/generated_poc/property/property_list_filters.py +9 -9
- adcp/types/generated_poc/property/update_property_list_request.py +9 -9
- adcp/types/generated_poc/property/update_property_list_response.py +3 -3
- adcp/types/generated_poc/protocol/__init__.py +3 -0
- adcp/types/generated_poc/protocol/get_adcp_capabilities_request.py +34 -0
- adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py +353 -0
- adcp/types/generated_poc/protocols/adcp_extension.py +14 -17
- adcp/types/generated_poc/signals/activate_signal_request.py +4 -4
- adcp/types/generated_poc/signals/activate_signal_response.py +7 -7
- adcp/types/generated_poc/signals/get_signals_request.py +9 -9
- adcp/types/generated_poc/signals/get_signals_response.py +16 -16
- adcp/types/generated_poc/sponsored_intelligence/__init__.py +3 -0
- adcp/types/generated_poc/sponsored_intelligence/si_capabilities.py +102 -0
- adcp/types/generated_poc/sponsored_intelligence/si_get_offering_request.py +34 -0
- adcp/types/generated_poc/sponsored_intelligence/si_get_offering_response.py +100 -0
- adcp/types/generated_poc/sponsored_intelligence/si_identity.py +78 -0
- adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_request.py +46 -0
- adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_response.py +44 -0
- adcp/types/generated_poc/sponsored_intelligence/si_send_message_request.py +58 -0
- adcp/types/generated_poc/sponsored_intelligence/si_send_message_response.py +101 -0
- adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_request.py +60 -0
- adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_response.py +54 -0
- adcp/types/generated_poc/sponsored_intelligence/si_ui_element.py +30 -0
- adcp/utils/format_assets.py +5 -5
- adcp/utils/preview_cache.py +2 -2
- {adcp-2.19.0.dist-info → adcp-3.1.0.dist-info}/METADATA +1 -1
- adcp-3.1.0.dist-info/RECORD +264 -0
- {adcp-2.19.0.dist-info → adcp-3.1.0.dist-info}/WHEEL +1 -1
- adcp/types/generated_poc/enums/standard_format_ids.py +0 -45
- adcp/types/generated_poc/pricing_options/cpm_auction_option.py +0 -58
- adcp/types/generated_poc/pricing_options/cpm_fixed_option.py +0 -43
- adcp/types/generated_poc/pricing_options/vcpm_auction_option.py +0 -61
- adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py +0 -47
- adcp/types/generated_poc/property/list_property_features_request.py +0 -25
- adcp/types/generated_poc/property/list_property_features_response.py +0 -24
- adcp-2.19.0.dist-info/RECORD +0 -220
- {adcp-2.19.0.dist-info → adcp-3.1.0.dist-info}/entry_points.txt +0 -0
- {adcp-2.19.0.dist-info → adcp-3.1.0.dist-info}/licenses/LICENSE +0 -0
- {adcp-2.19.0.dist-info → adcp-3.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/product_filters.json
|
|
3
|
-
# timestamp: 2026-01-
|
|
3
|
+
# timestamp: 2026-01-26T11:40:01+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -8,90 +8,155 @@ from datetime import date
|
|
|
8
8
|
from typing import Annotated
|
|
9
9
|
|
|
10
10
|
from adcp.types.base import AdCPBaseModel
|
|
11
|
-
from pydantic import ConfigDict, Field, RootModel
|
|
11
|
+
from pydantic import AnyUrl, ConfigDict, Field, RootModel
|
|
12
12
|
|
|
13
13
|
from ..enums import channels as channels_1
|
|
14
14
|
from ..enums import delivery_type as delivery_type_1
|
|
15
|
-
from ..enums import format_category
|
|
16
|
-
from . import format_id
|
|
15
|
+
from ..enums import format_category, geo_level, metro_system
|
|
16
|
+
from . import format_id, media_buy_features
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class BudgetRange(AdCPBaseModel):
|
|
20
20
|
model_config = ConfigDict(
|
|
21
|
-
extra=
|
|
21
|
+
extra='allow',
|
|
22
22
|
)
|
|
23
23
|
currency: Annotated[
|
|
24
24
|
str,
|
|
25
25
|
Field(
|
|
26
|
-
description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern=
|
|
26
|
+
description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern='^[A-Z]{3}$'
|
|
27
27
|
),
|
|
28
28
|
]
|
|
29
|
-
max: Annotated[float | None, Field(description=
|
|
30
|
-
min: Annotated[float, Field(description=
|
|
29
|
+
max: Annotated[float | None, Field(description='Maximum budget amount', ge=0.0)] = None
|
|
30
|
+
min: Annotated[float, Field(description='Minimum budget amount', ge=0.0)]
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class BudgetRange1(AdCPBaseModel):
|
|
34
34
|
model_config = ConfigDict(
|
|
35
|
-
extra=
|
|
35
|
+
extra='allow',
|
|
36
36
|
)
|
|
37
37
|
currency: Annotated[
|
|
38
38
|
str,
|
|
39
39
|
Field(
|
|
40
|
-
description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern=
|
|
40
|
+
description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern='^[A-Z]{3}$'
|
|
41
41
|
),
|
|
42
42
|
]
|
|
43
|
-
max: Annotated[float, Field(description=
|
|
44
|
-
min: Annotated[float | None, Field(description=
|
|
43
|
+
max: Annotated[float, Field(description='Maximum budget amount', ge=0.0)]
|
|
44
|
+
min: Annotated[float | None, Field(description='Minimum budget amount', ge=0.0)] = None
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class Country(RootModel[str]):
|
|
48
|
-
root: Annotated[str, Field(pattern=
|
|
48
|
+
root: Annotated[str, Field(pattern='^[A-Z]{2}$')]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Metro(AdCPBaseModel):
|
|
52
|
+
model_config = ConfigDict(
|
|
53
|
+
extra='forbid',
|
|
54
|
+
)
|
|
55
|
+
code: Annotated[
|
|
56
|
+
str, Field(description="Metro code within the system (e.g., '501' for NYC DMA)")
|
|
57
|
+
]
|
|
58
|
+
system: Annotated[
|
|
59
|
+
metro_system.MetroAreaSystem, Field(description='Metro classification system')
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class Region(RootModel[str]):
|
|
64
|
+
root: Annotated[str, Field(pattern='^[A-Z]{2}-[A-Z0-9]+$')]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class RequiredGeoTargetingItem(AdCPBaseModel):
|
|
68
|
+
model_config = ConfigDict(
|
|
69
|
+
extra='forbid',
|
|
70
|
+
)
|
|
71
|
+
level: Annotated[
|
|
72
|
+
geo_level.GeographicTargetingLevel,
|
|
73
|
+
Field(description='Geographic targeting level (country, region, metro, postal_area)'),
|
|
74
|
+
]
|
|
75
|
+
system: Annotated[
|
|
76
|
+
str | None,
|
|
77
|
+
Field(
|
|
78
|
+
description="Classification system within the level. Required for metro (e.g., 'nielsen_dma') and postal_area (e.g., 'us_zip'). Not applicable for country/region which use ISO standards."
|
|
79
|
+
),
|
|
80
|
+
] = None
|
|
49
81
|
|
|
50
82
|
|
|
51
83
|
class ProductFilters(AdCPBaseModel):
|
|
52
84
|
model_config = ConfigDict(
|
|
53
|
-
extra=
|
|
85
|
+
extra='allow',
|
|
54
86
|
)
|
|
55
87
|
budget_range: Annotated[
|
|
56
88
|
BudgetRange | BudgetRange1 | None,
|
|
57
|
-
Field(description=
|
|
89
|
+
Field(description='Budget range to filter appropriate products'),
|
|
58
90
|
] = None
|
|
59
91
|
channels: Annotated[
|
|
60
|
-
list[channels_1.
|
|
92
|
+
list[channels_1.MediaChannel] | None,
|
|
61
93
|
Field(description="Filter by advertising channels (e.g., ['display', 'video', 'dooh'])"),
|
|
62
94
|
] = None
|
|
63
95
|
countries: Annotated[
|
|
64
96
|
list[Country] | None,
|
|
65
97
|
Field(
|
|
66
|
-
description="Filter by
|
|
98
|
+
description="Filter by country coverage using ISO 3166-1 alpha-2 codes (e.g., ['US', 'CA', 'GB']). Works for all inventory types."
|
|
67
99
|
),
|
|
68
100
|
] = None
|
|
69
101
|
delivery_type: delivery_type_1.DeliveryType | None = None
|
|
70
102
|
end_date: Annotated[
|
|
71
103
|
date | None,
|
|
72
104
|
Field(
|
|
73
|
-
description=
|
|
105
|
+
description='Campaign end date (ISO 8601 date format: YYYY-MM-DD) for availability checks'
|
|
74
106
|
),
|
|
75
107
|
] = None
|
|
76
108
|
format_ids: Annotated[
|
|
77
|
-
list[format_id.FormatId] | None, Field(description=
|
|
109
|
+
list[format_id.FormatId] | None, Field(description='Filter by specific format IDs')
|
|
78
110
|
] = None
|
|
79
111
|
format_types: Annotated[
|
|
80
|
-
list[format_category.FormatCategory] | None, Field(description=
|
|
112
|
+
list[format_category.FormatCategory] | None, Field(description='Filter by format types')
|
|
81
113
|
] = None
|
|
82
114
|
is_fixed_price: Annotated[
|
|
83
|
-
bool | None,
|
|
115
|
+
bool | None,
|
|
116
|
+
Field(
|
|
117
|
+
description='Filter by pricing availability: true = products offering fixed pricing (at least one option with fixed_price), false = products offering auction pricing (at least one option without fixed_price). Products with both fixed and auction options match both true and false.'
|
|
118
|
+
),
|
|
119
|
+
] = None
|
|
120
|
+
metros: Annotated[
|
|
121
|
+
list[Metro] | None,
|
|
122
|
+
Field(
|
|
123
|
+
description='Filter by metro coverage for locally-bound inventory (radio, DOOH, local TV). Use when products have DMA/metro-specific coverage. For digital inventory where products have broad coverage, use required_geo_targeting instead to filter by seller capability.'
|
|
124
|
+
),
|
|
84
125
|
] = None
|
|
85
126
|
min_exposures: Annotated[
|
|
86
127
|
int | None,
|
|
87
|
-
Field(description=
|
|
128
|
+
Field(description='Minimum exposures/impressions needed for measurement validity', ge=1),
|
|
129
|
+
] = None
|
|
130
|
+
regions: Annotated[
|
|
131
|
+
list[Region] | None,
|
|
132
|
+
Field(
|
|
133
|
+
description="Filter by region coverage using ISO 3166-2 codes (e.g., ['US-NY', 'US-CA', 'GB-SCT']). Use for locally-bound inventory (regional OOH, local TV) where products have region-specific coverage."
|
|
134
|
+
),
|
|
135
|
+
] = None
|
|
136
|
+
required_axe_integrations: Annotated[
|
|
137
|
+
list[AnyUrl] | None,
|
|
138
|
+
Field(
|
|
139
|
+
description='Filter to products executable through specific agentic ad exchanges. URLs are canonical identifiers.'
|
|
140
|
+
),
|
|
141
|
+
] = None
|
|
142
|
+
required_features: Annotated[
|
|
143
|
+
media_buy_features.MediaBuyFeatures | None,
|
|
144
|
+
Field(
|
|
145
|
+
description='Filter to products from sellers supporting specific protocol features. Only features set to true are used for filtering.'
|
|
146
|
+
),
|
|
147
|
+
] = None
|
|
148
|
+
required_geo_targeting: Annotated[
|
|
149
|
+
list[RequiredGeoTargetingItem] | None,
|
|
150
|
+
Field(
|
|
151
|
+
description='Filter to products from sellers supporting specific geo targeting capabilities. Each entry specifies a targeting level (country, region, metro, postal_area) and optionally a system for levels that have multiple classification systems.'
|
|
152
|
+
),
|
|
88
153
|
] = None
|
|
89
154
|
standard_formats_only: Annotated[
|
|
90
|
-
bool | None, Field(description=
|
|
155
|
+
bool | None, Field(description='Only return products accepting IAB standard formats')
|
|
91
156
|
] = None
|
|
92
157
|
start_date: Annotated[
|
|
93
158
|
date | None,
|
|
94
159
|
Field(
|
|
95
|
-
description=
|
|
160
|
+
description='Campaign start date (ISO 8601 date format: YYYY-MM-DD) for availability checks'
|
|
96
161
|
),
|
|
97
162
|
] = None
|
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/promoted_offerings.json
|
|
3
|
-
# timestamp: 2026-01-
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
from enum import Enum
|
|
8
|
-
from typing import Annotated
|
|
8
|
+
from typing import Annotated
|
|
9
9
|
|
|
10
10
|
from adcp.types.base import AdCPBaseModel
|
|
11
|
-
from pydantic import ConfigDict, Field
|
|
11
|
+
from pydantic import AnyUrl, ConfigDict, Field
|
|
12
12
|
|
|
13
|
-
from . import brand_manifest_ref, promoted_products
|
|
13
|
+
from . import brand_manifest_ref, offering, promoted_products
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class AssetType(Enum):
|
|
17
|
-
image =
|
|
18
|
-
video =
|
|
19
|
-
audio =
|
|
20
|
-
vast =
|
|
21
|
-
daast =
|
|
22
|
-
text =
|
|
23
|
-
url =
|
|
24
|
-
html =
|
|
25
|
-
css =
|
|
26
|
-
javascript =
|
|
27
|
-
webhook =
|
|
17
|
+
image = 'image'
|
|
18
|
+
video = 'video'
|
|
19
|
+
audio = 'audio'
|
|
20
|
+
vast = 'vast'
|
|
21
|
+
daast = 'daast'
|
|
22
|
+
text = 'text'
|
|
23
|
+
url = 'url'
|
|
24
|
+
html = 'html'
|
|
25
|
+
css = 'css'
|
|
26
|
+
javascript = 'javascript'
|
|
27
|
+
webhook = 'webhook'
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class AssetSelectors(AdCPBaseModel):
|
|
31
31
|
model_config = ConfigDict(
|
|
32
|
-
extra=
|
|
32
|
+
extra='allow',
|
|
33
33
|
)
|
|
34
34
|
asset_types: Annotated[
|
|
35
35
|
list[AssetType] | None, Field(description="Filter by asset type (e.g., ['image', 'video'])")
|
|
36
36
|
] = None
|
|
37
37
|
exclude_tags: Annotated[
|
|
38
|
-
list[str] | None, Field(description=
|
|
38
|
+
list[str] | None, Field(description='Exclude assets with these tags')
|
|
39
39
|
] = None
|
|
40
40
|
tags: Annotated[
|
|
41
41
|
list[str] | None,
|
|
@@ -43,44 +43,35 @@ class AssetSelectors(AdCPBaseModel):
|
|
|
43
43
|
] = None
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
class Offering(AdCPBaseModel):
|
|
47
|
-
model_config = ConfigDict(
|
|
48
|
-
extra="allow",
|
|
49
|
-
)
|
|
50
|
-
assets: Annotated[
|
|
51
|
-
list[dict[str, Any]] | None, Field(description="Assets specific to this offering")
|
|
52
|
-
] = None
|
|
53
|
-
description: Annotated[str | None, Field(description="Description of what's being offered")] = (
|
|
54
|
-
None
|
|
55
|
-
)
|
|
56
|
-
name: Annotated[
|
|
57
|
-
str, Field(description="Offering name (e.g., 'Winter Sale', 'New Product Launch')")
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
|
|
61
46
|
class PromotedOfferings(AdCPBaseModel):
|
|
62
47
|
model_config = ConfigDict(
|
|
63
|
-
extra=
|
|
48
|
+
extra='allow',
|
|
64
49
|
)
|
|
65
50
|
asset_selectors: Annotated[
|
|
66
51
|
AssetSelectors | None,
|
|
67
|
-
Field(description=
|
|
52
|
+
Field(description='Selectors to choose specific assets from the brand manifest'),
|
|
68
53
|
] = None
|
|
69
54
|
brand_manifest: Annotated[
|
|
70
55
|
brand_manifest_ref.BrandManifestReference,
|
|
71
56
|
Field(
|
|
72
|
-
description=
|
|
57
|
+
description='Brand information manifest containing assets, themes, and guidelines. Can be provided inline or as a URL reference to a hosted manifest.'
|
|
73
58
|
),
|
|
74
59
|
]
|
|
75
60
|
offerings: Annotated[
|
|
76
|
-
list[Offering] | None,
|
|
61
|
+
list[offering.Offering] | None,
|
|
77
62
|
Field(
|
|
78
|
-
description=
|
|
63
|
+
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.'
|
|
79
64
|
),
|
|
80
65
|
] = None
|
|
81
66
|
product_selectors: Annotated[
|
|
82
67
|
promoted_products.PromotedProducts | None,
|
|
83
68
|
Field(
|
|
84
|
-
description=
|
|
69
|
+
description='Selectors to choose which products/offerings from the brand manifest product catalog to promote'
|
|
70
|
+
),
|
|
71
|
+
] = None
|
|
72
|
+
si_agent_url: Annotated[
|
|
73
|
+
AnyUrl | None,
|
|
74
|
+
Field(
|
|
75
|
+
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."
|
|
85
76
|
),
|
|
86
77
|
] = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/promoted_products.json
|
|
3
|
-
# timestamp: 2026-01-
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ from pydantic import ConfigDict, Field
|
|
|
12
12
|
|
|
13
13
|
class PromotedProducts(AdCPBaseModel):
|
|
14
14
|
model_config = ConfigDict(
|
|
15
|
-
extra=
|
|
15
|
+
extra='allow',
|
|
16
16
|
)
|
|
17
17
|
manifest_category: Annotated[
|
|
18
18
|
str | None,
|
|
@@ -28,7 +28,7 @@ class PromotedProducts(AdCPBaseModel):
|
|
|
28
28
|
] = None
|
|
29
29
|
manifest_skus: Annotated[
|
|
30
30
|
list[str] | None,
|
|
31
|
-
Field(description=
|
|
31
|
+
Field(description='Direct product SKU references from the brand manifest product catalog'),
|
|
32
32
|
] = None
|
|
33
33
|
manifest_tags: Annotated[
|
|
34
34
|
list[str] | None,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/property.json
|
|
3
|
-
# timestamp: 2026-01-
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -17,11 +17,11 @@ from . import property_tag
|
|
|
17
17
|
|
|
18
18
|
class Identifier(AdCPBaseModel):
|
|
19
19
|
model_config = ConfigDict(
|
|
20
|
-
extra=
|
|
20
|
+
extra='allow',
|
|
21
21
|
)
|
|
22
22
|
type: Annotated[
|
|
23
23
|
identifier_types.PropertyIdentifierTypes,
|
|
24
|
-
Field(description=
|
|
24
|
+
Field(description='Type of identifier for this property'),
|
|
25
25
|
]
|
|
26
26
|
value: Annotated[
|
|
27
27
|
str,
|
|
@@ -33,30 +33,30 @@ class Identifier(AdCPBaseModel):
|
|
|
33
33
|
|
|
34
34
|
class Property(AdCPBaseModel):
|
|
35
35
|
model_config = ConfigDict(
|
|
36
|
-
extra=
|
|
36
|
+
extra='allow',
|
|
37
37
|
)
|
|
38
38
|
identifiers: Annotated[
|
|
39
|
-
list[Identifier], Field(description=
|
|
39
|
+
list[Identifier], Field(description='Array of identifiers for this property', min_length=1)
|
|
40
40
|
]
|
|
41
|
-
name: Annotated[str, Field(description=
|
|
41
|
+
name: Annotated[str, Field(description='Human-readable property name')]
|
|
42
42
|
property_id: Annotated[
|
|
43
43
|
property_id_1.PropertyId | None,
|
|
44
44
|
Field(
|
|
45
|
-
description=
|
|
45
|
+
description='Unique identifier for this property (optional). Enables referencing properties by ID instead of repeating full objects.'
|
|
46
46
|
),
|
|
47
47
|
] = None
|
|
48
48
|
property_type: Annotated[
|
|
49
|
-
property_type_1.PropertyType, Field(description=
|
|
49
|
+
property_type_1.PropertyType, Field(description='Type of advertising property')
|
|
50
50
|
]
|
|
51
51
|
publisher_domain: Annotated[
|
|
52
52
|
str | None,
|
|
53
53
|
Field(
|
|
54
|
-
description=
|
|
54
|
+
description='Domain where adagents.json should be checked for authorization validation. Required for list_authorized_properties response. Optional in adagents.json (file location implies domain).'
|
|
55
55
|
),
|
|
56
56
|
] = None
|
|
57
57
|
tags: Annotated[
|
|
58
58
|
list[property_tag.PropertyTag] | None,
|
|
59
59
|
Field(
|
|
60
|
-
description=
|
|
60
|
+
description='Tags for categorization and grouping (e.g., network membership, content categories)'
|
|
61
61
|
),
|
|
62
62
|
] = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/property_id.json
|
|
3
|
-
# timestamp:
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -13,9 +13,9 @@ class PropertyId(RootModel[str]):
|
|
|
13
13
|
root: Annotated[
|
|
14
14
|
str,
|
|
15
15
|
Field(
|
|
16
|
-
description=
|
|
17
|
-
examples=[
|
|
18
|
-
pattern=
|
|
19
|
-
title=
|
|
16
|
+
description='Identifier for a publisher property. Must be lowercase alphanumeric with underscores only.',
|
|
17
|
+
examples=['cnn_ctv_app', 'homepage', 'mobile_ios', 'instagram'],
|
|
18
|
+
pattern='^[a-z0-9_]+$',
|
|
19
|
+
title='Property ID',
|
|
20
20
|
),
|
|
21
21
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/property_list_ref.json
|
|
3
|
-
# timestamp: 2026-01-
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -12,15 +12,15 @@ from pydantic import AnyUrl, ConfigDict, Field
|
|
|
12
12
|
|
|
13
13
|
class PropertyListReference(AdCPBaseModel):
|
|
14
14
|
model_config = ConfigDict(
|
|
15
|
-
extra=
|
|
15
|
+
extra='forbid',
|
|
16
16
|
)
|
|
17
|
-
agent_url: Annotated[AnyUrl, Field(description=
|
|
17
|
+
agent_url: Annotated[AnyUrl, Field(description='URL of the agent managing the property list')]
|
|
18
18
|
auth_token: Annotated[
|
|
19
19
|
str | None,
|
|
20
20
|
Field(
|
|
21
|
-
description=
|
|
21
|
+
description='JWT or other authorization token for accessing the list. Optional if the list is public or caller has implicit access.'
|
|
22
22
|
),
|
|
23
23
|
] = None
|
|
24
24
|
list_id: Annotated[
|
|
25
|
-
str, Field(description=
|
|
25
|
+
str, Field(description='Identifier for the property list within the agent', min_length=1)
|
|
26
26
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/property_tag.json
|
|
3
|
-
# timestamp:
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -13,9 +13,9 @@ class PropertyTag(RootModel[str]):
|
|
|
13
13
|
root: Annotated[
|
|
14
14
|
str,
|
|
15
15
|
Field(
|
|
16
|
-
description=
|
|
17
|
-
examples=[
|
|
18
|
-
pattern=
|
|
19
|
-
title=
|
|
16
|
+
description='Tag for categorizing publisher properties. Must be lowercase alphanumeric with underscores only.',
|
|
17
|
+
examples=['ctv', 'premium', 'news', 'sports', 'meta_network', 'social_media'],
|
|
18
|
+
pattern='^[a-z0-9_]+$',
|
|
19
|
+
title='Property Tag',
|
|
20
20
|
),
|
|
21
21
|
]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: core/proposal.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 . import ext as ext_1
|
|
13
|
+
from . import product_allocation
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TotalBudgetGuidance(AdCPBaseModel):
|
|
17
|
+
model_config = ConfigDict(
|
|
18
|
+
extra='allow',
|
|
19
|
+
)
|
|
20
|
+
currency: Annotated[str | None, Field(description='ISO 4217 currency code')] = None
|
|
21
|
+
max: Annotated[
|
|
22
|
+
float | None, Field(description='Maximum budget before diminishing returns', ge=0.0)
|
|
23
|
+
] = None
|
|
24
|
+
min: Annotated[float | None, Field(description='Minimum recommended budget', ge=0.0)] = None
|
|
25
|
+
recommended: Annotated[
|
|
26
|
+
float | None, Field(description='Recommended budget for optimal performance', ge=0.0)
|
|
27
|
+
] = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Proposal(AdCPBaseModel):
|
|
31
|
+
model_config = ConfigDict(
|
|
32
|
+
extra='allow',
|
|
33
|
+
)
|
|
34
|
+
allocations: Annotated[
|
|
35
|
+
list[product_allocation.ProductAllocation],
|
|
36
|
+
Field(
|
|
37
|
+
description='Budget allocations across products. Allocation percentages MUST sum to 100. Publishers are responsible for ensuring the sum equals 100; buyers SHOULD validate this before execution.',
|
|
38
|
+
min_length=1,
|
|
39
|
+
),
|
|
40
|
+
]
|
|
41
|
+
brief_alignment: Annotated[
|
|
42
|
+
str | None,
|
|
43
|
+
Field(description='Explanation of how this proposal aligns with the campaign brief'),
|
|
44
|
+
] = None
|
|
45
|
+
description: Annotated[
|
|
46
|
+
str | None, Field(description='Explanation of the proposal strategy and what it achieves')
|
|
47
|
+
] = None
|
|
48
|
+
expires_at: Annotated[
|
|
49
|
+
AwareDatetime | None,
|
|
50
|
+
Field(
|
|
51
|
+
description='When this proposal expires and can no longer be executed. After expiration, referenced products or pricing may no longer be available.'
|
|
52
|
+
),
|
|
53
|
+
] = None
|
|
54
|
+
ext: ext_1.ExtensionObject | None = None
|
|
55
|
+
name: Annotated[str, Field(description='Human-readable name for this media plan proposal')]
|
|
56
|
+
proposal_id: Annotated[
|
|
57
|
+
str,
|
|
58
|
+
Field(
|
|
59
|
+
description='Unique identifier for this proposal. Used to refine the proposal in subsequent get_products calls or to execute it via create_media_buy.'
|
|
60
|
+
),
|
|
61
|
+
]
|
|
62
|
+
total_budget_guidance: Annotated[
|
|
63
|
+
TotalBudgetGuidance | None, Field(description='Optional budget guidance for this proposal')
|
|
64
|
+
] = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: core/protocol_envelope.json
|
|
3
|
-
# timestamp: 2026-01-
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -15,47 +15,47 @@ from . import push_notification_config as push_notification_config_1
|
|
|
15
15
|
|
|
16
16
|
class ProtocolEnvelope(AdCPBaseModel):
|
|
17
17
|
model_config = ConfigDict(
|
|
18
|
-
extra=
|
|
18
|
+
extra='allow',
|
|
19
19
|
)
|
|
20
20
|
context_id: Annotated[
|
|
21
21
|
str | None,
|
|
22
22
|
Field(
|
|
23
|
-
description=
|
|
23
|
+
description='Session/conversation identifier for tracking related operations across multiple task invocations. Managed by the protocol layer to maintain conversational context.'
|
|
24
24
|
),
|
|
25
25
|
] = None
|
|
26
26
|
message: Annotated[
|
|
27
27
|
str | None,
|
|
28
28
|
Field(
|
|
29
|
-
description=
|
|
29
|
+
description='Human-readable summary of the task result. Provides natural language explanation of what happened, suitable for display to end users or for AI agent comprehension. Generated by the protocol layer based on the task response.'
|
|
30
30
|
),
|
|
31
31
|
] = None
|
|
32
32
|
payload: Annotated[
|
|
33
33
|
dict[str, Any],
|
|
34
34
|
Field(
|
|
35
|
-
description=
|
|
35
|
+
description='The actual task-specific response data. This is the content defined in individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json). Contains only domain-specific data without protocol-level fields.'
|
|
36
36
|
),
|
|
37
37
|
]
|
|
38
38
|
push_notification_config: Annotated[
|
|
39
39
|
push_notification_config_1.PushNotificationConfig | None,
|
|
40
40
|
Field(
|
|
41
|
-
description=
|
|
41
|
+
description='Push notification configuration for async task updates (A2A and REST protocols). Echoed from the request to confirm webhook settings. Specifies URL, authentication scheme (Bearer or HMAC-SHA256), and credentials. MCP uses progress notifications instead of webhooks.'
|
|
42
42
|
),
|
|
43
43
|
] = None
|
|
44
44
|
status: Annotated[
|
|
45
45
|
task_status.TaskStatus,
|
|
46
46
|
Field(
|
|
47
|
-
description=
|
|
47
|
+
description='Current task execution state. Indicates whether the task is completed, in progress (working), submitted for async processing, failed, or requires user input. Managed by the protocol layer.'
|
|
48
48
|
),
|
|
49
49
|
]
|
|
50
50
|
task_id: Annotated[
|
|
51
51
|
str | None,
|
|
52
52
|
Field(
|
|
53
|
-
description=
|
|
53
|
+
description='Unique identifier for tracking asynchronous operations. Present when a task requires extended processing time. Used to query task status and retrieve results when complete.'
|
|
54
54
|
),
|
|
55
55
|
] = None
|
|
56
56
|
timestamp: Annotated[
|
|
57
57
|
AwareDatetime | None,
|
|
58
58
|
Field(
|
|
59
|
-
description=
|
|
59
|
+
description='ISO 8601 timestamp when the response was generated. Useful for debugging, logging, cache validation, and tracking async operation progress.'
|
|
60
60
|
),
|
|
61
61
|
] = None
|