@adcp/client 4.21.0 → 4.22.1
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.
- package/AGENTS.md +278 -0
- package/README.md +96 -61
- package/bin/adcp.js +342 -4
- package/dist/lib/agents/index.generated.d.ts +9 -1
- package/dist/lib/agents/index.generated.d.ts.map +1 -1
- package/dist/lib/agents/index.generated.js +12 -0
- package/dist/lib/agents/index.generated.js.map +1 -1
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.ts +2 -1
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +10 -1
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/discovery/property-crawler.d.ts +4 -0
- package/dist/lib/discovery/property-crawler.d.ts.map +1 -1
- package/dist/lib/discovery/property-crawler.js +10 -2
- package/dist/lib/discovery/property-crawler.js.map +1 -1
- package/dist/lib/index.d.ts +4 -4
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +6 -4
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/protocols/index.d.ts.map +1 -1
- package/dist/lib/protocols/index.js +8 -6
- package/dist/lib/protocols/index.js.map +1 -1
- package/dist/lib/protocols/mcp.d.ts.map +1 -1
- package/dist/lib/protocols/mcp.js +24 -11
- package/dist/lib/protocols/mcp.js.map +1 -1
- package/dist/lib/server/index.d.ts +2 -0
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +3 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/serve.d.ts +73 -0
- package/dist/lib/server/serve.d.ts.map +1 -0
- package/dist/lib/server/serve.js +94 -0
- package/dist/lib/server/serve.js.map +1 -0
- package/dist/lib/testing/client.d.ts.map +1 -1
- package/dist/lib/testing/client.js +1 -0
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
- package/dist/lib/testing/compliance/comply.js +48 -63
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/storyboard-tracks.d.ts +24 -0
- package/dist/lib/testing/compliance/storyboard-tracks.d.ts.map +1 -0
- package/dist/lib/testing/compliance/storyboard-tracks.js +157 -0
- package/dist/lib/testing/compliance/storyboard-tracks.js.map +1 -0
- package/dist/lib/testing/compliance/types.d.ts +1 -1
- package/dist/lib/testing/compliance/types.d.ts.map +1 -1
- package/dist/lib/testing/index.d.ts +1 -0
- package/dist/lib/testing/index.d.ts.map +1 -1
- package/dist/lib/testing/index.js +23 -1
- package/dist/lib/testing/index.js.map +1 -1
- package/dist/lib/testing/orchestrator.d.ts +8 -0
- package/dist/lib/testing/orchestrator.d.ts.map +1 -1
- package/dist/lib/testing/orchestrator.js +8 -0
- package/dist/lib/testing/orchestrator.js.map +1 -1
- package/dist/lib/testing/storyboard/context.d.ts +34 -0
- package/dist/lib/testing/storyboard/context.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/context.js +257 -0
- package/dist/lib/testing/storyboard/context.js.map +1 -0
- package/dist/lib/testing/storyboard/index.d.ts +15 -0
- package/dist/lib/testing/storyboard/index.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/index.js +48 -0
- package/dist/lib/testing/storyboard/index.js.map +1 -0
- package/dist/lib/testing/storyboard/loader.d.ts +53 -0
- package/dist/lib/testing/storyboard/loader.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/loader.js +114 -0
- package/dist/lib/testing/storyboard/loader.js.map +1 -0
- package/dist/lib/testing/storyboard/path.d.ts +29 -0
- package/dist/lib/testing/storyboard/path.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/path.js +121 -0
- package/dist/lib/testing/storyboard/path.js.map +1 -0
- package/dist/lib/testing/storyboard/request-builder.d.ts +28 -0
- package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/request-builder.js +410 -0
- package/dist/lib/testing/storyboard/request-builder.js.map +1 -0
- package/dist/lib/testing/storyboard/runner.d.ts +24 -0
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/runner.js +280 -0
- package/dist/lib/testing/storyboard/runner.js.map +1 -0
- package/dist/lib/testing/storyboard/task-map.d.ts +21 -0
- package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/task-map.js +84 -0
- package/dist/lib/testing/storyboard/task-map.js.map +1 -0
- package/dist/lib/testing/storyboard/types.d.ts +156 -0
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/types.js +10 -0
- package/dist/lib/testing/storyboard/types.js.map +1 -0
- package/dist/lib/testing/storyboard/validations.d.ts +17 -0
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/validations.js +166 -0
- package/dist/lib/testing/storyboard/validations.js.map +1 -0
- package/dist/lib/testing/types.d.ts +2 -0
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/types/core.generated.d.ts +2 -2
- package/dist/lib/types/core.generated.d.ts.map +1 -1
- package/dist/lib/types/core.generated.js +1 -1
- package/dist/lib/types/schemas.generated.d.ts +193 -34
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js +87 -5
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/types/tools.generated.d.ts +280 -3
- package/dist/lib/types/tools.generated.d.ts.map +1 -1
- package/dist/lib/utils/response-schemas.d.ts.map +1 -1
- package/dist/lib/utils/response-schemas.js +34 -3
- package/dist/lib/utils/response-schemas.js.map +1 -1
- package/dist/lib/utils/validate-user-agent.d.ts +8 -0
- package/dist/lib/utils/validate-user-agent.d.ts.map +1 -0
- package/dist/lib/utils/validate-user-agent.js +15 -0
- package/dist/lib/utils/validate-user-agent.js.map +1 -0
- package/dist/lib/version.d.ts +6 -0
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +7 -1
- package/dist/lib/version.js.map +1 -1
- package/docs/README.md +42 -0
- package/docs/guides/BUILD-AN-AGENT.md +294 -0
- package/docs/llms.txt +634 -0
- package/examples/README.md +106 -0
- package/examples/adcp.config.json +30 -0
- package/examples/basic-a2a.ts +76 -0
- package/examples/basic-mcp.ts +50 -0
- package/examples/batch-preview-test.ts +266 -0
- package/examples/conversation-client.ts +291 -0
- package/examples/debug-preview-response.ts +73 -0
- package/examples/debug-preview-with-logging.ts +50 -0
- package/examples/easy-config-demo.ts +242 -0
- package/examples/env-config.ts +51 -0
- package/examples/error-compliant-server.ts +237 -0
- package/examples/generative-creative-demo.ts +205 -0
- package/examples/inspect-card-formats.ts +161 -0
- package/examples/logger-usage.ts +165 -0
- package/examples/oauth-cli-example.ts +154 -0
- package/examples/pr78-async-patterns-demo.ts +247 -0
- package/examples/signals-agent.ts +163 -0
- package/examples/simple-getting-started.ts +225 -0
- package/examples/simple-protocol-demo.ts +75 -0
- package/examples/test-helpers-demo.ts +239 -0
- package/examples/zod-validation-example.ts +126 -0
- package/package.json +12 -2
- package/skills/adcp/SKILL.md +13 -2
- package/storyboards/audience_sync.yaml +199 -0
- package/storyboards/behavioral_analysis.yaml +244 -0
- package/storyboards/brand_rights.yaml +131 -0
- package/storyboards/creative_ad_server.yaml +171 -0
- package/storyboards/creative_sales_agent.yaml +169 -0
- package/storyboards/creative_template.yaml +306 -0
- package/storyboards/deterministic_testing.yaml +925 -0
- package/storyboards/error_compliance.yaml +231 -0
- package/storyboards/governance_content_standards.yaml +213 -0
- package/storyboards/governance_property_lists.yaml +372 -0
- package/storyboards/media_buy_catalog_creative.yaml +457 -0
- package/storyboards/media_buy_governance_escalation.yaml +467 -0
- package/storyboards/media_buy_guaranteed_approval.yaml +396 -0
- package/storyboards/media_buy_non_guaranteed.yaml +288 -0
- package/storyboards/media_buy_proposal_mode.yaml +369 -0
- package/storyboards/media_buy_seller.yaml +560 -0
- package/storyboards/media_buy_state_machine.yaml +254 -0
- package/storyboards/schema.yaml +65 -0
- package/storyboards/schema_validation.yaml +166 -0
- package/storyboards/si_session.yaml +384 -0
- package/storyboards/signal_marketplace.yaml +283 -0
- package/storyboards/signal_owned.yaml +211 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
id: media_buy_proposal_mode
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Media buy via proposal acceptance"
|
|
4
|
+
category: media_buy_proposal_mode
|
|
5
|
+
summary: "Seller agent that generates curated media plan proposals the buyer can review, refine, and accept."
|
|
6
|
+
platform_types:
|
|
7
|
+
- dsp
|
|
8
|
+
- retail_media
|
|
9
|
+
- pmax_platform
|
|
10
|
+
- generative_dsp
|
|
11
|
+
|
|
12
|
+
track: media_buy
|
|
13
|
+
required_tools:
|
|
14
|
+
- create_media_buy
|
|
15
|
+
- get_products
|
|
16
|
+
narrative: |
|
|
17
|
+
Your seller generates curated media plan proposals. The buyer sends a brief, your platform
|
|
18
|
+
returns products alongside proposals — curated bundles with budget allocations and rationale
|
|
19
|
+
for each recommendation. The buyer reviews, optionally refines, and then accepts a proposal
|
|
20
|
+
as-is instead of manually building packages.
|
|
21
|
+
|
|
22
|
+
Proposal mode is the recommended flow for buyers who trust the seller's product
|
|
23
|
+
recommendations. Instead of the buyer cherry-picking individual products and assembling
|
|
24
|
+
packages, the seller's AI builds an optimized media plan that the buyer can accept with a
|
|
25
|
+
single call.
|
|
26
|
+
|
|
27
|
+
This storyboard walks through the proposal lifecycle: brief, proposal generation, optional
|
|
28
|
+
refinement, acceptance, creative sync, and delivery monitoring.
|
|
29
|
+
|
|
30
|
+
agent:
|
|
31
|
+
interaction_model: media_buy_seller
|
|
32
|
+
capabilities:
|
|
33
|
+
- sells_media
|
|
34
|
+
- accepts_briefs
|
|
35
|
+
- generates_proposals
|
|
36
|
+
examples:
|
|
37
|
+
- "Full-service publisher with AI planning"
|
|
38
|
+
- "Retail media network with curated packages"
|
|
39
|
+
- "Premium video platform with proposal engine"
|
|
40
|
+
|
|
41
|
+
caller:
|
|
42
|
+
role: buyer_agent
|
|
43
|
+
example: "Pinnacle Agency (buyer)"
|
|
44
|
+
|
|
45
|
+
prerequisites:
|
|
46
|
+
description: |
|
|
47
|
+
The caller needs a brand identity and operator credentials for account setup.
|
|
48
|
+
The test kit provides a sample brand (Acme Outdoor) with campaign parameters
|
|
49
|
+
suitable for testing the proposal acceptance flow.
|
|
50
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
51
|
+
|
|
52
|
+
phases:
|
|
53
|
+
- id: account_setup
|
|
54
|
+
title: "Account setup"
|
|
55
|
+
narrative: |
|
|
56
|
+
The buyer establishes an account relationship with your platform before
|
|
57
|
+
requesting proposals.
|
|
58
|
+
|
|
59
|
+
steps:
|
|
60
|
+
- id: sync_accounts
|
|
61
|
+
title: "Establish account relationship"
|
|
62
|
+
narrative: |
|
|
63
|
+
The buyer registers their brand and operator with your platform.
|
|
64
|
+
task: sync_accounts
|
|
65
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
66
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
67
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
68
|
+
stateful: true
|
|
69
|
+
expected: |
|
|
70
|
+
Return the account with:
|
|
71
|
+
- account_id: your platform's identifier for this relationship
|
|
72
|
+
- action: created or updated
|
|
73
|
+
- status: active or pending_approval
|
|
74
|
+
- payment_terms: net_30, prepay, etc.
|
|
75
|
+
|
|
76
|
+
sample_request:
|
|
77
|
+
accounts:
|
|
78
|
+
- brand:
|
|
79
|
+
domain: "acmeoutdoor.com"
|
|
80
|
+
operator: "pinnacle-agency.com"
|
|
81
|
+
billing: "operator"
|
|
82
|
+
payment_terms: "net_30"
|
|
83
|
+
|
|
84
|
+
validations:
|
|
85
|
+
- check: response_schema
|
|
86
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
87
|
+
- check: field_present
|
|
88
|
+
path: "accounts[0].account_id"
|
|
89
|
+
description: "Account has a platform-assigned ID"
|
|
90
|
+
|
|
91
|
+
- id: brief_with_proposals
|
|
92
|
+
title: "Brief with proposals"
|
|
93
|
+
narrative: |
|
|
94
|
+
The buyer sends a brief. Your platform returns products and — because you support
|
|
95
|
+
proposal mode — also returns proposals: curated media plans with budget allocations,
|
|
96
|
+
product selections, and rationale for each recommendation. The buyer can review
|
|
97
|
+
multiple proposals side by side.
|
|
98
|
+
|
|
99
|
+
steps:
|
|
100
|
+
- id: get_products_brief
|
|
101
|
+
title: "Send a brief and receive proposals"
|
|
102
|
+
narrative: |
|
|
103
|
+
The buyer describes what they want. Your platform returns products alongside
|
|
104
|
+
one or more proposals. Each proposal bundles products with budget allocations
|
|
105
|
+
and explains why those products were selected and how the budget was distributed.
|
|
106
|
+
|
|
107
|
+
Proposals give the buyer a ready-to-accept media plan instead of requiring
|
|
108
|
+
manual package assembly.
|
|
109
|
+
task: get_products
|
|
110
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
111
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
112
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
113
|
+
stateful: false
|
|
114
|
+
expected: |
|
|
115
|
+
Return products and proposals matching the brief:
|
|
116
|
+
- products: individual products with pricing and forecasts
|
|
117
|
+
- proposals: curated media plans, each containing:
|
|
118
|
+
- proposal_id: unique identifier for this proposal
|
|
119
|
+
- name: descriptive label (e.g., "Balanced Reach Plan")
|
|
120
|
+
- budget_allocations: how the total budget is split across products
|
|
121
|
+
- rationale: why these products were selected and how the budget was distributed
|
|
122
|
+
- total_budget: sum of allocations
|
|
123
|
+
- forecast: aggregate impressions, reach, frequency
|
|
124
|
+
|
|
125
|
+
sample_request:
|
|
126
|
+
buying_mode: "brief"
|
|
127
|
+
brief: "Premium video and display across outdoor lifestyle and sports. Q2 flight, $50K total budget. Adults 25-54, US and Canada. Looking for a balanced plan across CTV, online video, and display."
|
|
128
|
+
brand:
|
|
129
|
+
domain: "acmeoutdoor.com"
|
|
130
|
+
account:
|
|
131
|
+
brand:
|
|
132
|
+
domain: "acmeoutdoor.com"
|
|
133
|
+
operator: "pinnacle-agency.com"
|
|
134
|
+
|
|
135
|
+
validations:
|
|
136
|
+
- check: response_schema
|
|
137
|
+
description: "Response matches get-products-response.json schema"
|
|
138
|
+
- check: field_present
|
|
139
|
+
path: "products"
|
|
140
|
+
description: "Response contains a products array"
|
|
141
|
+
- check: field_present
|
|
142
|
+
path: "proposals"
|
|
143
|
+
description: "Response contains a proposals array"
|
|
144
|
+
- check: field_present
|
|
145
|
+
path: "proposals[0].proposal_id"
|
|
146
|
+
description: "Each proposal has a proposal_id"
|
|
147
|
+
|
|
148
|
+
- id: review_refine
|
|
149
|
+
title: "Refine a proposal"
|
|
150
|
+
narrative: |
|
|
151
|
+
The buyer reviews the proposals and wants to adjust one. They call get_products
|
|
152
|
+
in refine mode targeting a specific proposal_id. The refinement might adjust
|
|
153
|
+
budget splits, swap a product, or add constraints. Your platform returns the
|
|
154
|
+
updated proposal.
|
|
155
|
+
|
|
156
|
+
steps:
|
|
157
|
+
- id: get_products_refine
|
|
158
|
+
title: "Refine a specific proposal"
|
|
159
|
+
narrative: |
|
|
160
|
+
The buyer targets a specific proposal for refinement. They reference the
|
|
161
|
+
proposal_id and describe what they want to change. Your platform applies
|
|
162
|
+
the refinements to that proposal and returns the updated version.
|
|
163
|
+
task: get_products
|
|
164
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
165
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
166
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
167
|
+
stateful: true
|
|
168
|
+
expected: |
|
|
169
|
+
Return the refined proposal:
|
|
170
|
+
- proposals: updated proposal reflecting the requested changes
|
|
171
|
+
- refinement_applied: how each refinement was handled
|
|
172
|
+
- Updated budget allocations, product selections, and forecasts
|
|
173
|
+
- products: updated product set if products were swapped
|
|
174
|
+
|
|
175
|
+
sample_request:
|
|
176
|
+
buying_mode: "refine"
|
|
177
|
+
refine:
|
|
178
|
+
- scope: "proposal"
|
|
179
|
+
proposal_id: "balanced_reach_q2"
|
|
180
|
+
ask: "Shift 60% of budget to CTV. Drop the display product and redistribute that budget to video."
|
|
181
|
+
- scope: "request"
|
|
182
|
+
ask: "All products must support frequency capping at 3 per day."
|
|
183
|
+
brand:
|
|
184
|
+
domain: "acmeoutdoor.com"
|
|
185
|
+
account:
|
|
186
|
+
brand:
|
|
187
|
+
domain: "acmeoutdoor.com"
|
|
188
|
+
operator: "pinnacle-agency.com"
|
|
189
|
+
|
|
190
|
+
validations:
|
|
191
|
+
- check: response_schema
|
|
192
|
+
description: "Response matches get-products-response.json schema"
|
|
193
|
+
- check: field_present
|
|
194
|
+
path: "proposals"
|
|
195
|
+
description: "Response contains updated proposals"
|
|
196
|
+
|
|
197
|
+
- id: accept_proposal
|
|
198
|
+
title: "Accept the proposal"
|
|
199
|
+
narrative: |
|
|
200
|
+
The buyer is satisfied with the refined proposal and accepts it by creating a
|
|
201
|
+
media buy with the proposal_id. Instead of specifying individual packages, the
|
|
202
|
+
buyer passes the proposal_id and total_budget. Your platform converts the proposal
|
|
203
|
+
into a confirmed media buy with the exact product selections and budget allocations
|
|
204
|
+
from the proposal.
|
|
205
|
+
|
|
206
|
+
steps:
|
|
207
|
+
- id: create_media_buy
|
|
208
|
+
title: "Create a media buy from proposal"
|
|
209
|
+
narrative: |
|
|
210
|
+
The buyer accepts a proposal by passing proposal_id to create_media_buy. The
|
|
211
|
+
buyer does NOT specify a packages array — the platform uses the proposal's
|
|
212
|
+
product selections and budget allocations to build the packages automatically.
|
|
213
|
+
|
|
214
|
+
This is the key difference from manual package creation: the buyer trusts the
|
|
215
|
+
seller's recommendation and accepts the plan as-is.
|
|
216
|
+
task: create_media_buy
|
|
217
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
218
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
219
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
220
|
+
stateful: true
|
|
221
|
+
expected: |
|
|
222
|
+
Convert the proposal into a confirmed media buy:
|
|
223
|
+
- media_buy_id: your platform's identifier
|
|
224
|
+
- status: confirmed or active
|
|
225
|
+
- confirmed_at: timestamp
|
|
226
|
+
- packages: line items derived from the proposal's budget allocations
|
|
227
|
+
- proposal_id: echoed back to confirm which proposal was accepted
|
|
228
|
+
- valid_actions: creative sync, pause, get_delivery
|
|
229
|
+
|
|
230
|
+
sample_request:
|
|
231
|
+
account:
|
|
232
|
+
brand:
|
|
233
|
+
domain: "acmeoutdoor.com"
|
|
234
|
+
operator: "pinnacle-agency.com"
|
|
235
|
+
brand:
|
|
236
|
+
domain: "acmeoutdoor.com"
|
|
237
|
+
proposal_id: "balanced_reach_q2"
|
|
238
|
+
total_budget: 50000
|
|
239
|
+
start_time: "2026-04-01T00:00:00Z"
|
|
240
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
241
|
+
|
|
242
|
+
validations:
|
|
243
|
+
- check: response_schema
|
|
244
|
+
description: "Response matches create-media-buy-response.json schema"
|
|
245
|
+
|
|
246
|
+
- id: creative_sync
|
|
247
|
+
title: "Creative sync"
|
|
248
|
+
narrative: |
|
|
249
|
+
With the proposal accepted and the media buy confirmed, the buyer syncs creative
|
|
250
|
+
assets. The buyer first checks what formats the accepted products require, then
|
|
251
|
+
pushes matching creative assets.
|
|
252
|
+
|
|
253
|
+
steps:
|
|
254
|
+
- id: list_formats
|
|
255
|
+
title: "Check creative format requirements"
|
|
256
|
+
narrative: |
|
|
257
|
+
The buyer confirms what creative formats the accepted proposal's products
|
|
258
|
+
require. Your platform returns format specs with asset requirements.
|
|
259
|
+
task: list_creative_formats
|
|
260
|
+
schema_ref: "creative/list-creative-formats-request.json"
|
|
261
|
+
response_schema_ref: "creative/list-creative-formats-response.json"
|
|
262
|
+
doc_ref: "/creative/task-reference/list_creative_formats"
|
|
263
|
+
stateful: false
|
|
264
|
+
expected: |
|
|
265
|
+
Return creative formats your platform accepts. Each format should define:
|
|
266
|
+
- format_id with your agent_url and unique id
|
|
267
|
+
- Asset requirements (dimensions, file sizes, mime types)
|
|
268
|
+
- Render dimensions
|
|
269
|
+
|
|
270
|
+
sample_request: {}
|
|
271
|
+
|
|
272
|
+
validations:
|
|
273
|
+
- check: response_schema
|
|
274
|
+
description: "Response matches list-creative-formats-response.json schema"
|
|
275
|
+
- check: field_present
|
|
276
|
+
path: "formats"
|
|
277
|
+
description: "Response contains formats array"
|
|
278
|
+
|
|
279
|
+
- id: sync_creatives
|
|
280
|
+
title: "Push creative assets"
|
|
281
|
+
narrative: |
|
|
282
|
+
The buyer uploads creative assets for the products in the accepted proposal.
|
|
283
|
+
Your platform validates each creative against the format specs and returns
|
|
284
|
+
per-creative status.
|
|
285
|
+
task: sync_creatives
|
|
286
|
+
schema_ref: "creative/sync-creatives-request.json"
|
|
287
|
+
response_schema_ref: "creative/sync-creatives-response.json"
|
|
288
|
+
doc_ref: "/creative/task-reference/sync_creatives"
|
|
289
|
+
stateful: true
|
|
290
|
+
expected: |
|
|
291
|
+
Accept and validate creatives:
|
|
292
|
+
- Per-creative action: created or updated
|
|
293
|
+
- Per-creative status: accepted, pending_review, or rejected
|
|
294
|
+
- Validation errors for rejected creatives
|
|
295
|
+
|
|
296
|
+
sample_request:
|
|
297
|
+
account:
|
|
298
|
+
brand:
|
|
299
|
+
domain: "acmeoutdoor.com"
|
|
300
|
+
operator: "pinnacle-agency.com"
|
|
301
|
+
creatives:
|
|
302
|
+
- creative_id: "video_30s_trail_pro"
|
|
303
|
+
name: "Trail Pro 3000 - 30s CTV Spot"
|
|
304
|
+
format_id:
|
|
305
|
+
agent_url: "https://your-platform.example.com"
|
|
306
|
+
id: "ssai_30s"
|
|
307
|
+
assets:
|
|
308
|
+
- asset_id: "video"
|
|
309
|
+
asset_type: "video"
|
|
310
|
+
url: "https://cdn.pinnacle-agency.example/trail-pro-30s.mp4"
|
|
311
|
+
mime_type: "video/mp4"
|
|
312
|
+
- creative_id: "video_15s_trail_pro"
|
|
313
|
+
name: "Trail Pro 3000 - 15s Online Video"
|
|
314
|
+
format_id:
|
|
315
|
+
agent_url: "https://your-platform.example.com"
|
|
316
|
+
id: "preroll_15s"
|
|
317
|
+
assets:
|
|
318
|
+
- asset_id: "video"
|
|
319
|
+
asset_type: "video"
|
|
320
|
+
url: "https://cdn.pinnacle-agency.example/trail-pro-15s.mp4"
|
|
321
|
+
mime_type: "video/mp4"
|
|
322
|
+
|
|
323
|
+
validations:
|
|
324
|
+
- check: response_schema
|
|
325
|
+
description: "Response matches sync-creatives-response.json schema"
|
|
326
|
+
- check: field_present
|
|
327
|
+
path: "creatives[0].action"
|
|
328
|
+
description: "Each creative has an action (created/updated)"
|
|
329
|
+
|
|
330
|
+
- id: delivery
|
|
331
|
+
title: "Delivery and reporting"
|
|
332
|
+
narrative: |
|
|
333
|
+
The campaign from the accepted proposal is live. The buyer monitors delivery
|
|
334
|
+
to verify the proposal's forecasts are tracking.
|
|
335
|
+
|
|
336
|
+
steps:
|
|
337
|
+
- id: get_delivery
|
|
338
|
+
title: "Check delivery metrics"
|
|
339
|
+
narrative: |
|
|
340
|
+
The buyer requests delivery data for the media buy created from the proposal.
|
|
341
|
+
Your platform returns performance metrics that the buyer can compare against
|
|
342
|
+
the proposal's original forecasts.
|
|
343
|
+
task: get_media_buy_delivery
|
|
344
|
+
schema_ref: "media-buy/get-media-buy-delivery-request.json"
|
|
345
|
+
response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
|
|
346
|
+
doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
|
|
347
|
+
stateful: true
|
|
348
|
+
expected: |
|
|
349
|
+
Return delivery metrics for the media buy:
|
|
350
|
+
- Per-package delivery: impressions, clicks, spend, completion rates
|
|
351
|
+
- Pacing against the proposal's original forecast
|
|
352
|
+
- Budget utilization: spent vs. committed per package
|
|
353
|
+
- Daily breakdown if requested
|
|
354
|
+
|
|
355
|
+
sample_request:
|
|
356
|
+
account:
|
|
357
|
+
brand:
|
|
358
|
+
domain: "acmeoutdoor.com"
|
|
359
|
+
operator: "pinnacle-agency.com"
|
|
360
|
+
media_buy_ids:
|
|
361
|
+
- "mb_acme_q2_2026_proposal"
|
|
362
|
+
include_package_daily_breakdown: true
|
|
363
|
+
|
|
364
|
+
validations:
|
|
365
|
+
- check: response_schema
|
|
366
|
+
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
367
|
+
- check: field_present
|
|
368
|
+
path: "media_buys"
|
|
369
|
+
description: "Response contains media buy delivery data"
|