@adcp/client 4.20.0 → 4.22.0

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 (210) hide show
  1. package/AGENTS.md +278 -0
  2. package/README.md +96 -61
  3. package/bin/adcp.js +342 -4
  4. package/dist/lib/agents/index.generated.d.ts +9 -1
  5. package/dist/lib/agents/index.generated.d.ts.map +1 -1
  6. package/dist/lib/agents/index.generated.js +12 -0
  7. package/dist/lib/agents/index.generated.js.map +1 -1
  8. package/dist/lib/core/AgentClient.d.ts.map +1 -1
  9. package/dist/lib/core/SingleAgentClient.d.ts +2 -1
  10. package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
  11. package/dist/lib/core/SingleAgentClient.js +10 -1
  12. package/dist/lib/core/SingleAgentClient.js.map +1 -1
  13. package/dist/lib/discovery/property-crawler.d.ts +4 -0
  14. package/dist/lib/discovery/property-crawler.d.ts.map +1 -1
  15. package/dist/lib/discovery/property-crawler.js +10 -2
  16. package/dist/lib/discovery/property-crawler.js.map +1 -1
  17. package/dist/lib/index.d.ts +9 -9
  18. package/dist/lib/index.d.ts.map +1 -1
  19. package/dist/lib/index.js +13 -5
  20. package/dist/lib/index.js.map +1 -1
  21. package/dist/lib/protocols/index.d.ts.map +1 -1
  22. package/dist/lib/protocols/index.js +8 -6
  23. package/dist/lib/protocols/index.js.map +1 -1
  24. package/dist/lib/protocols/mcp.d.ts.map +1 -1
  25. package/dist/lib/protocols/mcp.js +24 -11
  26. package/dist/lib/protocols/mcp.js.map +1 -1
  27. package/dist/lib/registry/cursor-store.d.ts +19 -0
  28. package/dist/lib/registry/cursor-store.d.ts.map +1 -0
  29. package/dist/lib/registry/cursor-store.js +44 -0
  30. package/dist/lib/registry/cursor-store.js.map +1 -0
  31. package/dist/lib/registry/index.d.ts +21 -3
  32. package/dist/lib/registry/index.d.ts.map +1 -1
  33. package/dist/lib/registry/index.js +94 -1
  34. package/dist/lib/registry/index.js.map +1 -1
  35. package/dist/lib/registry/property-registry.d.ts +57 -0
  36. package/dist/lib/registry/property-registry.d.ts.map +1 -0
  37. package/dist/lib/registry/property-registry.js +92 -0
  38. package/dist/lib/registry/property-registry.js.map +1 -0
  39. package/dist/lib/registry/sync.d.ts +4 -0
  40. package/dist/lib/registry/sync.d.ts.map +1 -1
  41. package/dist/lib/registry/sync.js +14 -0
  42. package/dist/lib/registry/sync.js.map +1 -1
  43. package/dist/lib/registry/types.d.ts +35 -2
  44. package/dist/lib/registry/types.d.ts.map +1 -1
  45. package/dist/lib/registry/types.generated.d.ts +349 -321
  46. package/dist/lib/registry/types.generated.d.ts.map +1 -1
  47. package/dist/lib/registry/types.generated.js +1 -1
  48. package/dist/lib/server/index.d.ts +2 -0
  49. package/dist/lib/server/index.d.ts.map +1 -1
  50. package/dist/lib/server/index.js +3 -1
  51. package/dist/lib/server/index.js.map +1 -1
  52. package/dist/lib/server/serve.d.ts +45 -0
  53. package/dist/lib/server/serve.d.ts.map +1 -0
  54. package/dist/lib/server/serve.js +86 -0
  55. package/dist/lib/server/serve.js.map +1 -0
  56. package/dist/lib/testing/agent-tester.d.ts +1 -1
  57. package/dist/lib/testing/agent-tester.d.ts.map +1 -1
  58. package/dist/lib/testing/agent-tester.js +10 -1
  59. package/dist/lib/testing/agent-tester.js.map +1 -1
  60. package/dist/lib/testing/client.d.ts.map +1 -1
  61. package/dist/lib/testing/client.js +3 -0
  62. package/dist/lib/testing/client.js.map +1 -1
  63. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  64. package/dist/lib/testing/compliance/comply.js +158 -203
  65. package/dist/lib/testing/compliance/comply.js.map +1 -1
  66. package/dist/lib/testing/compliance/storyboard-tracks.d.ts +24 -0
  67. package/dist/lib/testing/compliance/storyboard-tracks.d.ts.map +1 -0
  68. package/dist/lib/testing/compliance/storyboard-tracks.js +157 -0
  69. package/dist/lib/testing/compliance/storyboard-tracks.js.map +1 -0
  70. package/dist/lib/testing/compliance/types.d.ts +1 -1
  71. package/dist/lib/testing/compliance/types.d.ts.map +1 -1
  72. package/dist/lib/testing/index.d.ts +2 -1
  73. package/dist/lib/testing/index.d.ts.map +1 -1
  74. package/dist/lib/testing/index.js +26 -1
  75. package/dist/lib/testing/index.js.map +1 -1
  76. package/dist/lib/testing/orchestrator.d.ts +8 -0
  77. package/dist/lib/testing/orchestrator.d.ts.map +1 -1
  78. package/dist/lib/testing/orchestrator.js +11 -0
  79. package/dist/lib/testing/orchestrator.js.map +1 -1
  80. package/dist/lib/testing/scenarios/brand-rights.d.ts +23 -0
  81. package/dist/lib/testing/scenarios/brand-rights.d.ts.map +1 -0
  82. package/dist/lib/testing/scenarios/brand-rights.js +144 -0
  83. package/dist/lib/testing/scenarios/brand-rights.js.map +1 -0
  84. package/dist/lib/testing/scenarios/capabilities.d.ts.map +1 -1
  85. package/dist/lib/testing/scenarios/capabilities.js +11 -2
  86. package/dist/lib/testing/scenarios/capabilities.js.map +1 -1
  87. package/dist/lib/testing/scenarios/governance.d.ts.map +1 -1
  88. package/dist/lib/testing/scenarios/governance.js +5 -0
  89. package/dist/lib/testing/scenarios/governance.js.map +1 -1
  90. package/dist/lib/testing/scenarios/index.d.ts +2 -0
  91. package/dist/lib/testing/scenarios/index.d.ts.map +1 -1
  92. package/dist/lib/testing/scenarios/index.js +10 -2
  93. package/dist/lib/testing/scenarios/index.js.map +1 -1
  94. package/dist/lib/testing/scenarios/media-buy.d.ts.map +1 -1
  95. package/dist/lib/testing/scenarios/media-buy.js +22 -3
  96. package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
  97. package/dist/lib/testing/scenarios/trusted-match.d.ts +22 -0
  98. package/dist/lib/testing/scenarios/trusted-match.d.ts.map +1 -0
  99. package/dist/lib/testing/scenarios/trusted-match.js +128 -0
  100. package/dist/lib/testing/scenarios/trusted-match.js.map +1 -0
  101. package/dist/lib/testing/storyboard/context.d.ts +34 -0
  102. package/dist/lib/testing/storyboard/context.d.ts.map +1 -0
  103. package/dist/lib/testing/storyboard/context.js +257 -0
  104. package/dist/lib/testing/storyboard/context.js.map +1 -0
  105. package/dist/lib/testing/storyboard/index.d.ts +15 -0
  106. package/dist/lib/testing/storyboard/index.d.ts.map +1 -0
  107. package/dist/lib/testing/storyboard/index.js +48 -0
  108. package/dist/lib/testing/storyboard/index.js.map +1 -0
  109. package/dist/lib/testing/storyboard/loader.d.ts +53 -0
  110. package/dist/lib/testing/storyboard/loader.d.ts.map +1 -0
  111. package/dist/lib/testing/storyboard/loader.js +114 -0
  112. package/dist/lib/testing/storyboard/loader.js.map +1 -0
  113. package/dist/lib/testing/storyboard/path.d.ts +29 -0
  114. package/dist/lib/testing/storyboard/path.d.ts.map +1 -0
  115. package/dist/lib/testing/storyboard/path.js +121 -0
  116. package/dist/lib/testing/storyboard/path.js.map +1 -0
  117. package/dist/lib/testing/storyboard/request-builder.d.ts +28 -0
  118. package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -0
  119. package/dist/lib/testing/storyboard/request-builder.js +410 -0
  120. package/dist/lib/testing/storyboard/request-builder.js.map +1 -0
  121. package/dist/lib/testing/storyboard/runner.d.ts +24 -0
  122. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -0
  123. package/dist/lib/testing/storyboard/runner.js +280 -0
  124. package/dist/lib/testing/storyboard/runner.js.map +1 -0
  125. package/dist/lib/testing/storyboard/task-map.d.ts +21 -0
  126. package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -0
  127. package/dist/lib/testing/storyboard/task-map.js +84 -0
  128. package/dist/lib/testing/storyboard/task-map.js.map +1 -0
  129. package/dist/lib/testing/storyboard/types.d.ts +156 -0
  130. package/dist/lib/testing/storyboard/types.d.ts.map +1 -0
  131. package/dist/lib/testing/storyboard/types.js +10 -0
  132. package/dist/lib/testing/storyboard/types.js.map +1 -0
  133. package/dist/lib/testing/storyboard/validations.d.ts +17 -0
  134. package/dist/lib/testing/storyboard/validations.d.ts.map +1 -0
  135. package/dist/lib/testing/storyboard/validations.js +166 -0
  136. package/dist/lib/testing/storyboard/validations.js.map +1 -0
  137. package/dist/lib/testing/types.d.ts +4 -1
  138. package/dist/lib/testing/types.d.ts.map +1 -1
  139. package/dist/lib/types/core.generated.d.ts +36 -23
  140. package/dist/lib/types/core.generated.d.ts.map +1 -1
  141. package/dist/lib/types/core.generated.js +1 -1
  142. package/dist/lib/types/schemas.generated.d.ts +1098 -770
  143. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  144. package/dist/lib/types/schemas.generated.js +163 -76
  145. package/dist/lib/types/schemas.generated.js.map +1 -1
  146. package/dist/lib/types/tools.generated.d.ts +314 -24
  147. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  148. package/dist/lib/utils/capabilities.d.ts +4 -1
  149. package/dist/lib/utils/capabilities.d.ts.map +1 -1
  150. package/dist/lib/utils/capabilities.js +25 -1
  151. package/dist/lib/utils/capabilities.js.map +1 -1
  152. package/dist/lib/utils/response-schemas.d.ts.map +1 -1
  153. package/dist/lib/utils/response-schemas.js +34 -3
  154. package/dist/lib/utils/response-schemas.js.map +1 -1
  155. package/dist/lib/utils/validate-user-agent.d.ts +8 -0
  156. package/dist/lib/utils/validate-user-agent.d.ts.map +1 -0
  157. package/dist/lib/utils/validate-user-agent.js +15 -0
  158. package/dist/lib/utils/validate-user-agent.js.map +1 -0
  159. package/dist/lib/version.d.ts +9 -3
  160. package/dist/lib/version.d.ts.map +1 -1
  161. package/dist/lib/version.js +10 -4
  162. package/dist/lib/version.js.map +1 -1
  163. package/docs/README.md +42 -0
  164. package/docs/guides/BUILD-AN-AGENT.md +292 -0
  165. package/docs/llms.txt +634 -0
  166. package/examples/README.md +106 -0
  167. package/examples/adcp.config.json +30 -0
  168. package/examples/basic-a2a.ts +76 -0
  169. package/examples/basic-mcp.ts +50 -0
  170. package/examples/batch-preview-test.ts +266 -0
  171. package/examples/conversation-client.ts +291 -0
  172. package/examples/debug-preview-response.ts +73 -0
  173. package/examples/debug-preview-with-logging.ts +50 -0
  174. package/examples/easy-config-demo.ts +242 -0
  175. package/examples/env-config.ts +51 -0
  176. package/examples/error-compliant-server.ts +237 -0
  177. package/examples/generative-creative-demo.ts +205 -0
  178. package/examples/inspect-card-formats.ts +161 -0
  179. package/examples/logger-usage.ts +165 -0
  180. package/examples/oauth-cli-example.ts +154 -0
  181. package/examples/pr78-async-patterns-demo.ts +247 -0
  182. package/examples/signals-agent.ts +162 -0
  183. package/examples/simple-getting-started.ts +225 -0
  184. package/examples/simple-protocol-demo.ts +75 -0
  185. package/examples/test-helpers-demo.ts +239 -0
  186. package/examples/zod-validation-example.ts +126 -0
  187. package/package.json +12 -2
  188. package/skills/adcp/SKILL.md +13 -2
  189. package/storyboards/audience_sync.yaml +199 -0
  190. package/storyboards/behavioral_analysis.yaml +244 -0
  191. package/storyboards/brand_rights.yaml +131 -0
  192. package/storyboards/creative_ad_server.yaml +171 -0
  193. package/storyboards/creative_sales_agent.yaml +169 -0
  194. package/storyboards/creative_template.yaml +306 -0
  195. package/storyboards/deterministic_testing.yaml +925 -0
  196. package/storyboards/error_compliance.yaml +231 -0
  197. package/storyboards/governance_content_standards.yaml +213 -0
  198. package/storyboards/governance_property_lists.yaml +372 -0
  199. package/storyboards/media_buy_catalog_creative.yaml +457 -0
  200. package/storyboards/media_buy_governance_escalation.yaml +467 -0
  201. package/storyboards/media_buy_guaranteed_approval.yaml +396 -0
  202. package/storyboards/media_buy_non_guaranteed.yaml +288 -0
  203. package/storyboards/media_buy_proposal_mode.yaml +369 -0
  204. package/storyboards/media_buy_seller.yaml +560 -0
  205. package/storyboards/media_buy_state_machine.yaml +254 -0
  206. package/storyboards/schema.yaml +65 -0
  207. package/storyboards/schema_validation.yaml +166 -0
  208. package/storyboards/si_session.yaml +384 -0
  209. package/storyboards/signal_marketplace.yaml +283 -0
  210. package/storyboards/signal_owned.yaml +211 -0
@@ -0,0 +1,457 @@
1
+ id: media_buy_catalog_creative
2
+ version: "1.0.0"
3
+ title: "Catalog-driven creative and conversion tracking"
4
+ category: media_buy_catalog_creative
5
+ summary: "Seller that renders dynamic ads from product catalogs, tracks conversions, and optimizes delivery based on performance feedback."
6
+ platform_types:
7
+ - retail_media
8
+
9
+ track: media_buy
10
+ required_tools:
11
+ - create_media_buy
12
+ - sync_creatives
13
+ narrative: |
14
+ You run a platform that supports catalog-driven advertising — think Snap Dynamic Ads,
15
+ Meta Product Catalogs, or retail media product listing ads. The buyer pushes a product
16
+ catalog (menu items, retail products, hotel listings), and your platform renders ads
17
+ dynamically from that feed. When a user converts, events are logged back and attributed
18
+ to catalog items, closing the optimization loop.
19
+
20
+ This storyboard walks through the full catalog-to-conversion flow: account setup,
21
+ catalog sync, creative formats for catalog items, media buy with catalog packages,
22
+ event source configuration, conversion logging, and performance feedback.
23
+
24
+ The key difference from the standard media buy flow is that creatives are catalog-driven —
25
+ the buyer doesn't build individual ads. They push a feed, and your platform renders
26
+ the right item to the right user at the right time.
27
+
28
+ agent:
29
+ interaction_model: media_buy_seller
30
+ capabilities:
31
+ - sells_media
32
+ - accepts_catalogs
33
+ - supports_conversion_tracking
34
+ - catalog_driven_creative
35
+ examples:
36
+ - "Snap (Dynamic Ads)"
37
+ - "Retail media networks"
38
+ - "Travel platforms"
39
+ - "Local commerce platforms"
40
+
41
+ caller:
42
+ role: buyer_agent
43
+ example: "Scope3 (DSP)"
44
+
45
+ prerequisites:
46
+ description: |
47
+ The caller needs a product catalog (feed URL or inline items) and an event source
48
+ for conversion tracking. The test kit provides a sample brand with catalog-compatible
49
+ assets.
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. For catalog-driven
57
+ campaigns, the account must be active before any catalog sync can happen.
58
+
59
+ steps:
60
+ - id: sync_accounts
61
+ title: "Establish account"
62
+ narrative: |
63
+ The buyer registers their brand and operator. Sandbox accounts are provisioned
64
+ instantly for testing catalog flows.
65
+ task: sync_accounts
66
+ schema_ref: "account/sync-accounts-request.json"
67
+ response_schema_ref: "account/sync-accounts-response.json"
68
+ doc_ref: "/accounts/tasks/sync_accounts"
69
+ stateful: true
70
+ expected: |
71
+ Return the account with account_id, status (active for sandbox), and billing terms.
72
+
73
+ sample_request:
74
+ accounts:
75
+ - brand:
76
+ domain: "amsterdam-steakhouse.com"
77
+ name: "Amsterdam Steakhouse"
78
+ operator: "pinnacle-agency.com"
79
+ billing: "operator"
80
+ sandbox: true
81
+
82
+ validations:
83
+ - check: response_schema
84
+ description: "Response matches sync-accounts-response.json schema"
85
+ - check: field_present
86
+ path: "accounts[0].account_id"
87
+ description: "Account has a platform-assigned ID"
88
+
89
+ - id: catalog_sync
90
+ title: "Product catalog sync"
91
+ narrative: |
92
+ The buyer pushes their product catalog to your platform. This is the foundation of
93
+ catalog-driven advertising — every ad your platform renders comes from this feed.
94
+
95
+ For a restaurant, this is the menu. For retail, it is the product feed. For travel,
96
+ it is hotel or flight listings. Your platform validates each item against your
97
+ format requirements (image dimensions, required fields, pricing format) and returns
98
+ per-item approval status.
99
+
100
+ Large feeds may go async — the buyer gets back a submitted status and waits for
101
+ your platform to finish processing. Small feeds (inline items) are processed
102
+ synchronously.
103
+
104
+ steps:
105
+ - id: discover_catalog_formats
106
+ title: "Check catalog format requirements"
107
+ narrative: |
108
+ Before pushing catalog items, the buyer checks what creative formats your
109
+ platform supports for catalog-driven ads. This tells the buyer what image
110
+ dimensions, text lengths, and required fields each catalog item needs.
111
+ task: list_creative_formats
112
+ schema_ref: "creative/list-creative-formats-request.json"
113
+ response_schema_ref: "creative/list-creative-formats-response.json"
114
+ doc_ref: "/creative/task-reference/list_creative_formats"
115
+ stateful: false
116
+ expected: |
117
+ Return creative formats that accept catalog assets. Look for formats with
118
+ catalog-specific asset slots (product_image, product_title, price, description).
119
+
120
+ sample_request:
121
+ channels: ["display", "native"]
122
+
123
+ validations:
124
+ - check: response_schema
125
+ description: "Response matches list-creative-formats-response.json schema"
126
+ - check: field_present
127
+ path: "formats"
128
+ description: "Response contains formats array"
129
+
130
+ - id: sync_catalogs
131
+ title: "Push product catalog"
132
+ narrative: |
133
+ The buyer pushes their product feed. This can be a URL to an existing feed
134
+ (your platform fetches and re-fetches on a schedule) or inline items for
135
+ small catalogs.
136
+
137
+ Your platform validates each item: images meet minimum dimensions, required
138
+ fields are present, prices are formatted correctly. Items that fail validation
139
+ are rejected with specific reasons. Items that pass are approved and available
140
+ for dynamic creative rendering.
141
+ task: sync_catalogs
142
+ schema_ref: "media-buy/sync-catalogs-request.json"
143
+ response_schema_ref: "media-buy/sync-catalogs-response.json"
144
+ doc_ref: "/media-buy/task-reference/sync_catalogs"
145
+ stateful: true
146
+ expected: |
147
+ Return per-catalog results with:
148
+ - catalog_id and action (created/updated)
149
+ - item_count, items_approved, items_pending, items_rejected
150
+ - item_issues for rejected items with specific reasons
151
+ - next_fetch_at for URL-based feeds
152
+
153
+ sample_request:
154
+ account:
155
+ brand:
156
+ domain: "amsterdam-steakhouse.com"
157
+ operator: "pinnacle-agency.com"
158
+ catalogs:
159
+ - catalog_id: "menu_spring_2026"
160
+ catalog_type: "product"
161
+ name: "Spring 2026 Menu"
162
+ items:
163
+ - item_id: "ribeye_36oz"
164
+ title: "36oz Tomahawk Ribeye"
165
+ description: "Dry-aged 45 days, served with truffle butter and roasted bone marrow"
166
+ url: "https://amsterdam-steakhouse.com/menu/ribeye-36oz"
167
+ image_url: "https://cdn.amsterdam-steakhouse.com/menu/ribeye-36oz-hero.jpg"
168
+ price:
169
+ amount: 89.00
170
+ currency: "USD"
171
+ - item_id: "seafood_tower"
172
+ title: "Grand Seafood Tower"
173
+ description: "Oysters, king crab, lobster tail, shrimp cocktail, tuna tartare"
174
+ url: "https://amsterdam-steakhouse.com/menu/seafood-tower"
175
+ image_url: "https://cdn.amsterdam-steakhouse.com/menu/seafood-tower-hero.jpg"
176
+ price:
177
+ amount: 145.00
178
+ currency: "USD"
179
+ - item_id: "wagyu_flight"
180
+ title: "A5 Wagyu Tasting Flight"
181
+ description: "Three cuts of Japanese A5 Wagyu — striploin, ribeye cap, tenderloin"
182
+ url: "https://amsterdam-steakhouse.com/menu/wagyu-flight"
183
+ image_url: "https://cdn.amsterdam-steakhouse.com/menu/wagyu-flight-hero.jpg"
184
+ price:
185
+ amount: 195.00
186
+ currency: "USD"
187
+
188
+ validations:
189
+ - check: response_schema
190
+ description: "Response matches sync-catalogs-response.json schema"
191
+ - check: field_present
192
+ path: "catalogs[0].catalog_id"
193
+ description: "Catalog has an ID"
194
+ - check: field_present
195
+ path: "catalogs[0].item_count"
196
+ description: "Catalog reports item count"
197
+ - check: field_present
198
+ path: "catalogs[0].items_approved"
199
+ description: "Catalog reports approved item count"
200
+
201
+ - id: create_buy
202
+ title: "Create catalog-driven media buy"
203
+ narrative: |
204
+ The buyer creates a media buy with catalog-driven packages. Instead of assigning
205
+ individual creatives, the buyer references the synced catalog. Your platform
206
+ renders the right catalog items dynamically based on user context, intent signals,
207
+ and inventory availability.
208
+
209
+ The key schema difference: packages include a catalogs[] array instead of (or
210
+ alongside) creative_assignments[].
211
+
212
+ steps:
213
+ - id: get_products
214
+ title: "Discover catalog-compatible products"
215
+ narrative: |
216
+ The buyer finds products that support catalog-driven delivery. These products
217
+ accept catalog references and render dynamic ads from the feed.
218
+ task: get_products
219
+ schema_ref: "media-buy/get-products-request.json"
220
+ response_schema_ref: "media-buy/get-products-response.json"
221
+ doc_ref: "/media-buy/task-reference/get_products"
222
+ stateful: false
223
+ expected: |
224
+ Return products that support catalog-driven creative. Products should indicate
225
+ catalog compatibility in their format requirements.
226
+
227
+ sample_request:
228
+ buying_mode: "brief"
229
+ brief: "Dynamic product ads for a high-end steakhouse. Geo-targeted to 10 miles around Amsterdam location. Drive reservations and foot traffic."
230
+ brand:
231
+ domain: "amsterdam-steakhouse.com"
232
+ account:
233
+ brand:
234
+ domain: "amsterdam-steakhouse.com"
235
+ operator: "pinnacle-agency.com"
236
+
237
+ validations:
238
+ - check: response_schema
239
+ description: "Response matches get-products-response.json schema"
240
+ - check: field_present
241
+ path: "products"
242
+ description: "Response contains products"
243
+
244
+ - id: create_media_buy
245
+ title: "Create media buy with catalog packages"
246
+ narrative: |
247
+ The buyer creates the media buy with packages that reference the synced catalog.
248
+ Each package has a catalogs[] array specifying which catalog feeds drive the
249
+ dynamic creative for that line item.
250
+
251
+ Your platform optimizes across catalog items within each package's budget
252
+ envelope — showing the ribeye to steak lovers and the seafood tower to
253
+ seafood enthusiasts.
254
+ task: create_media_buy
255
+ schema_ref: "media-buy/create-media-buy-request.json"
256
+ response_schema_ref: "media-buy/create-media-buy-response.json"
257
+ doc_ref: "/media-buy/task-reference/create_media_buy"
258
+ stateful: true
259
+ expected: |
260
+ Create the media buy with catalog-driven packages. Return:
261
+ - media_buy_id
262
+ - status: active or confirmed
263
+ - packages with catalog references preserved
264
+
265
+ sample_request:
266
+ account:
267
+ brand:
268
+ domain: "amsterdam-steakhouse.com"
269
+ operator: "pinnacle-agency.com"
270
+ brand:
271
+ domain: "amsterdam-steakhouse.com"
272
+ start_time: "2026-04-07T00:00:00Z"
273
+ end_time: "2026-06-30T23:59:59Z"
274
+ packages:
275
+ - product_id: "local_display_dynamic"
276
+ pricing_option_id: "cpm_standard"
277
+ budget: 5000
278
+ catalogs:
279
+ - catalog_id: "menu_spring_2026"
280
+ catalog_type: "product"
281
+
282
+ validations:
283
+ - check: response_schema
284
+ description: "Response matches create-media-buy-response.json schema"
285
+
286
+ - id: event_setup
287
+ title: "Conversion tracking setup"
288
+ narrative: |
289
+ The buyer configures event sources so your platform can attribute conversions to
290
+ catalog items. For a restaurant, the events are reservations and walk-ins. For
291
+ retail, they are purchases and add-to-carts.
292
+
293
+ Your platform returns setup snippets (pixel code, SDK instructions) that the
294
+ buyer installs on their conversion surfaces.
295
+
296
+ steps:
297
+ - id: sync_event_sources
298
+ title: "Configure event sources"
299
+ narrative: |
300
+ The buyer tells your platform where conversion events will come from —
301
+ a website pixel, a mobile SDK, or a server-to-server integration. Your
302
+ platform returns the integration code.
303
+ task: sync_event_sources
304
+ schema_ref: "media-buy/sync-event-sources-request.json"
305
+ response_schema_ref: "media-buy/sync-event-sources-response.json"
306
+ doc_ref: "/media-buy/task-reference/sync_event_sources"
307
+ stateful: true
308
+ expected: |
309
+ Return event sources with:
310
+ - event_source_id and seller_id
311
+ - setup.snippet: integration code (JavaScript pixel, HTML tag, or pixel URL)
312
+ - setup.instructions: human-readable integration guide
313
+ - action: created or updated
314
+
315
+ sample_request:
316
+ account:
317
+ brand:
318
+ domain: "amsterdam-steakhouse.com"
319
+ operator: "pinnacle-agency.com"
320
+ event_sources:
321
+ - event_source_id: "amsterdam_website"
322
+ name: "Amsterdam Steakhouse Website"
323
+ event_types: ["purchase", "add_to_cart", "page_view", "lead"]
324
+ allowed_domains: ["amsterdam-steakhouse.com", "book.amsterdam-steakhouse.com"]
325
+
326
+ validations:
327
+ - check: response_schema
328
+ description: "Response matches sync-event-sources-response.json schema"
329
+ - check: field_present
330
+ path: "event_sources[0].setup.snippet"
331
+ description: "Event source includes setup snippet"
332
+
333
+ - id: conversion_tracking
334
+ title: "Log conversions"
335
+ narrative: |
336
+ The campaign is running and customers are converting. The buyer logs conversion
337
+ events back to your platform, attributing them to catalog items via content_ids.
338
+
339
+ When someone books a reservation after seeing the ribeye ad, the event includes
340
+ content_ids: ["ribeye_36oz"] — linking the conversion to the catalog item that
341
+ drove it. Your platform uses this signal to optimize which items to show.
342
+
343
+ steps:
344
+ - id: log_events
345
+ title: "Send conversion events"
346
+ narrative: |
347
+ The buyer sends a batch of conversion events. Each event includes the event
348
+ type, value, and content_ids linking to catalog items. Your platform processes
349
+ these for attribution and optimization.
350
+ task: log_event
351
+ schema_ref: "media-buy/log-event-request.json"
352
+ response_schema_ref: "media-buy/log-event-response.json"
353
+ doc_ref: "/media-buy/task-reference/log_event"
354
+ stateful: true
355
+ expected: |
356
+ Process the events and return:
357
+ - events_received and events_processed counts
358
+ - partial_failures for events that failed validation
359
+ - match_quality: how well events matched to ad exposures (0.0-1.0)
360
+
361
+ sample_request:
362
+ event_source_id: "amsterdam_website"
363
+ events:
364
+ - event_id: "evt_001"
365
+ event_type: "purchase"
366
+ timestamp: "2026-04-15T19:30:00Z"
367
+ content_ids: ["ribeye_36oz"]
368
+ value: 89.00
369
+ currency: "USD"
370
+ - event_id: "evt_002"
371
+ event_type: "lead"
372
+ timestamp: "2026-04-15T20:15:00Z"
373
+ content_ids: ["wagyu_flight"]
374
+ value: 195.00
375
+ currency: "USD"
376
+ - event_id: "evt_003"
377
+ event_type: "page_view"
378
+ timestamp: "2026-04-15T20:45:00Z"
379
+ content_ids: ["seafood_tower"]
380
+
381
+ validations:
382
+ - check: response_schema
383
+ description: "Response matches log-event-response.json schema"
384
+ - check: field_present
385
+ path: "events_received"
386
+ description: "Response reports events received"
387
+ - check: field_present
388
+ path: "match_quality"
389
+ description: "Response includes match quality score"
390
+
391
+ - id: optimization_loop
392
+ title: "Performance feedback and optimization"
393
+ narrative: |
394
+ The buyer closes the optimization loop by telling your platform how the campaign
395
+ is performing against their goals. A performance_index above 1.0 means the
396
+ campaign is exceeding expectations — your platform should maintain or increase
397
+ delivery. Below 1.0 means underperforming — your platform should adjust targeting,
398
+ item selection, or pacing.
399
+
400
+ steps:
401
+ - id: provide_feedback
402
+ title: "Submit performance feedback"
403
+ narrative: |
404
+ The buyer reports that the campaign is driving 1.4x the expected reservation
405
+ rate. Your platform uses this signal to optimize delivery — showing more of
406
+ the high-performing catalog items and adjusting bid strategies.
407
+ task: provide_performance_feedback
408
+ schema_ref: "media-buy/provide-performance-feedback-request.json"
409
+ response_schema_ref: "media-buy/provide-performance-feedback-response.json"
410
+ doc_ref: "/media-buy/task-reference/provide_performance_feedback"
411
+ stateful: true
412
+ expected: |
413
+ Acknowledge the feedback. The seller should adjust delivery optimization
414
+ based on the performance_index signal.
415
+
416
+ sample_request:
417
+ media_buy_id: "mb_amsterdam_spring_2026"
418
+ measurement_period:
419
+ start: "2026-04-07T00:00:00Z"
420
+ end: "2026-04-14T23:59:59Z"
421
+ performance_index: 1.4
422
+ metric_type: "conversion_rate"
423
+ feedback_source: "buyer_attribution"
424
+
425
+ validations:
426
+ - check: response_schema
427
+ description: "Response matches provide-performance-feedback-response.json schema"
428
+ - check: field_value
429
+ path: "success"
430
+ description: "Feedback accepted"
431
+
432
+ - id: check_delivery
433
+ title: "Monitor delivery with catalog attribution"
434
+ narrative: |
435
+ The buyer checks delivery metrics to see which catalog items are driving
436
+ performance and how spend is allocated across the product feed.
437
+ task: get_media_buy_delivery
438
+ schema_ref: "media-buy/get-media-buy-delivery-request.json"
439
+ response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
440
+ doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
441
+ stateful: true
442
+ expected: |
443
+ Return delivery metrics including impressions, clicks, spend, and
444
+ conversion data attributed to catalog items.
445
+
446
+ sample_request:
447
+ account:
448
+ brand:
449
+ domain: "amsterdam-steakhouse.com"
450
+ operator: "pinnacle-agency.com"
451
+ media_buy_ids:
452
+ - "mb_amsterdam_spring_2026"
453
+ include_package_daily_breakdown: true
454
+
455
+ validations:
456
+ - check: response_schema
457
+ description: "Response matches get-media-buy-delivery-response.json schema"