@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.
- 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 +9 -9
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +13 -5
- 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/registry/cursor-store.d.ts +19 -0
- package/dist/lib/registry/cursor-store.d.ts.map +1 -0
- package/dist/lib/registry/cursor-store.js +44 -0
- package/dist/lib/registry/cursor-store.js.map +1 -0
- package/dist/lib/registry/index.d.ts +21 -3
- package/dist/lib/registry/index.d.ts.map +1 -1
- package/dist/lib/registry/index.js +94 -1
- package/dist/lib/registry/index.js.map +1 -1
- package/dist/lib/registry/property-registry.d.ts +57 -0
- package/dist/lib/registry/property-registry.d.ts.map +1 -0
- package/dist/lib/registry/property-registry.js +92 -0
- package/dist/lib/registry/property-registry.js.map +1 -0
- package/dist/lib/registry/sync.d.ts +4 -0
- package/dist/lib/registry/sync.d.ts.map +1 -1
- package/dist/lib/registry/sync.js +14 -0
- package/dist/lib/registry/sync.js.map +1 -1
- package/dist/lib/registry/types.d.ts +35 -2
- package/dist/lib/registry/types.d.ts.map +1 -1
- package/dist/lib/registry/types.generated.d.ts +349 -321
- package/dist/lib/registry/types.generated.d.ts.map +1 -1
- package/dist/lib/registry/types.generated.js +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 +45 -0
- package/dist/lib/server/serve.d.ts.map +1 -0
- package/dist/lib/server/serve.js +86 -0
- package/dist/lib/server/serve.js.map +1 -0
- package/dist/lib/testing/agent-tester.d.ts +1 -1
- package/dist/lib/testing/agent-tester.d.ts.map +1 -1
- package/dist/lib/testing/agent-tester.js +10 -1
- package/dist/lib/testing/agent-tester.js.map +1 -1
- package/dist/lib/testing/client.d.ts.map +1 -1
- package/dist/lib/testing/client.js +3 -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 +158 -203
- 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 +2 -1
- package/dist/lib/testing/index.d.ts.map +1 -1
- package/dist/lib/testing/index.js +26 -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 +11 -0
- package/dist/lib/testing/orchestrator.js.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.d.ts +23 -0
- package/dist/lib/testing/scenarios/brand-rights.d.ts.map +1 -0
- package/dist/lib/testing/scenarios/brand-rights.js +144 -0
- package/dist/lib/testing/scenarios/brand-rights.js.map +1 -0
- package/dist/lib/testing/scenarios/capabilities.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/capabilities.js +11 -2
- package/dist/lib/testing/scenarios/capabilities.js.map +1 -1
- package/dist/lib/testing/scenarios/governance.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/governance.js +5 -0
- package/dist/lib/testing/scenarios/governance.js.map +1 -1
- package/dist/lib/testing/scenarios/index.d.ts +2 -0
- package/dist/lib/testing/scenarios/index.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/index.js +10 -2
- package/dist/lib/testing/scenarios/index.js.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.js +22 -3
- package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.d.ts +22 -0
- package/dist/lib/testing/scenarios/trusted-match.d.ts.map +1 -0
- package/dist/lib/testing/scenarios/trusted-match.js +128 -0
- package/dist/lib/testing/scenarios/trusted-match.js.map +1 -0
- 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 +4 -1
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/types/core.generated.d.ts +36 -23
- 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 +1098 -770
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js +163 -76
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/types/tools.generated.d.ts +314 -24
- package/dist/lib/types/tools.generated.d.ts.map +1 -1
- package/dist/lib/utils/capabilities.d.ts +4 -1
- package/dist/lib/utils/capabilities.d.ts.map +1 -1
- package/dist/lib/utils/capabilities.js +25 -1
- package/dist/lib/utils/capabilities.js.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 +9 -3
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +10 -4
- package/dist/lib/version.js.map +1 -1
- package/docs/README.md +42 -0
- package/docs/guides/BUILD-AN-AGENT.md +292 -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 +162 -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,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"
|