@adcp/client 4.0.1 → 4.1.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 (57) hide show
  1. package/dist/lib/adapters/content-standards-adapter.d.ts.map +1 -1
  2. package/dist/lib/adapters/content-standards-adapter.js +2 -0
  3. package/dist/lib/adapters/content-standards-adapter.js.map +1 -1
  4. package/dist/lib/core/AgentClient.d.ts.map +1 -1
  5. package/dist/lib/core/SingleAgentClient.d.ts +0 -14
  6. package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
  7. package/dist/lib/core/SingleAgentClient.js +29 -72
  8. package/dist/lib/core/SingleAgentClient.js.map +1 -1
  9. package/dist/lib/index.d.ts +6 -2
  10. package/dist/lib/index.d.ts.map +1 -1
  11. package/dist/lib/index.js +12 -4
  12. package/dist/lib/index.js.map +1 -1
  13. package/dist/lib/types/adcp.d.ts +2 -5
  14. package/dist/lib/types/adcp.d.ts.map +1 -1
  15. package/dist/lib/types/compat.d.ts +3 -0
  16. package/dist/lib/types/compat.d.ts.map +1 -1
  17. package/dist/lib/types/compat.js.map +1 -1
  18. package/dist/lib/types/core.generated.d.ts +731 -226
  19. package/dist/lib/types/core.generated.d.ts.map +1 -1
  20. package/dist/lib/types/core.generated.js +1 -1
  21. package/dist/lib/types/error-codes.d.ts +32 -0
  22. package/dist/lib/types/error-codes.d.ts.map +1 -0
  23. package/dist/lib/types/error-codes.js +114 -0
  24. package/dist/lib/types/error-codes.js.map +1 -0
  25. package/dist/lib/types/index.d.ts +1 -1
  26. package/dist/lib/types/index.d.ts.map +1 -1
  27. package/dist/lib/types/index.js.map +1 -1
  28. package/dist/lib/types/schemas.generated.d.ts +23334 -8549
  29. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  30. package/dist/lib/types/schemas.generated.js +644 -462
  31. package/dist/lib/types/schemas.generated.js.map +1 -1
  32. package/dist/lib/types/tools.generated.d.ts +1360 -925
  33. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  34. package/dist/lib/utils/creative-adapter.d.ts +1 -1
  35. package/dist/lib/utils/creative-adapter.js +2 -2
  36. package/dist/lib/utils/creative-adapter.js.map +1 -1
  37. package/dist/lib/utils/deprecation.d.ts +11 -0
  38. package/dist/lib/utils/deprecation.d.ts.map +1 -0
  39. package/dist/lib/utils/deprecation.js +23 -0
  40. package/dist/lib/utils/deprecation.js.map +1 -0
  41. package/dist/lib/utils/index.d.ts +1 -0
  42. package/dist/lib/utils/index.d.ts.map +1 -1
  43. package/dist/lib/utils/index.js +4 -1
  44. package/dist/lib/utils/index.js.map +1 -1
  45. package/dist/lib/utils/request-normalizer.d.ts +23 -0
  46. package/dist/lib/utils/request-normalizer.d.ts.map +1 -0
  47. package/dist/lib/utils/request-normalizer.js +119 -0
  48. package/dist/lib/utils/request-normalizer.js.map +1 -0
  49. package/dist/lib/utils/sync-creatives-adapter.d.ts +18 -0
  50. package/dist/lib/utils/sync-creatives-adapter.d.ts.map +1 -0
  51. package/dist/lib/utils/sync-creatives-adapter.js +46 -0
  52. package/dist/lib/utils/sync-creatives-adapter.js.map +1 -0
  53. package/dist/lib/version.d.ts +3 -3
  54. package/dist/lib/version.d.ts.map +1 -1
  55. package/dist/lib/version.js +3 -3
  56. package/dist/lib/version.js.map +1 -1
  57. package/package.json +1 -1
@@ -3,13 +3,33 @@
3
3
  */
4
4
  export type BrandID = string;
5
5
  /**
6
- * Status of a media buy
6
+ * Status of a media buy.
7
7
  */
8
- export type MediaBuyStatus = 'pending_activation' | 'active' | 'paused' | 'completed';
8
+ export type MediaBuyStatus = 'pending_activation' | 'active' | 'paused' | 'completed' | 'rejected' | 'canceled';
9
9
  /**
10
10
  * Budget pacing strategy
11
11
  */
12
12
  export type Pacing = 'even' | 'asap' | 'front_loaded';
13
+ /**
14
+ * Catalog type. Structural types: 'offering' (AdCP Offering objects), 'product' (ecommerce entries), 'inventory' (stock per location), 'store' (physical locations), 'promotion' (deals and pricing). Vertical types: 'hotel', 'flight', 'job', 'vehicle', 'real_estate', 'education', 'destination', 'app' — each with an industry-specific item schema.
15
+ */
16
+ export type CatalogType = 'offering' | 'product' | 'inventory' | 'store' | 'promotion' | 'hotel' | 'flight' | 'job' | 'vehicle' | 'real_estate' | 'education' | 'destination' | 'app';
17
+ /**
18
+ * Format of the external feed at url. Required when url points to a non-AdCP feed (e.g., Google Merchant Center XML, Meta Product Catalog). Omit for offering-type catalogs where the feed is native AdCP JSON.
19
+ */
20
+ export type FeedFormat = 'google_merchant_center' | 'facebook_catalog' | 'shopify' | 'linkedin_jobs' | 'custom';
21
+ /**
22
+ * How often the platform should re-fetch the feed from url. Only applicable when url is provided. Platforms may use this as a hint for polling schedules.
23
+ */
24
+ export type UpdateFrequency = 'realtime' | 'hourly' | 'daily' | 'weekly';
25
+ /**
26
+ * Standard marketing event types for event logging, aligned with IAB ECAPI
27
+ */
28
+ export type EventType = 'page_view' | 'view_content' | 'select_content' | 'select_item' | 'search' | 'share' | 'add_to_cart' | 'remove_from_cart' | 'viewed_cart' | 'add_to_wishlist' | 'initiate_checkout' | 'add_payment_info' | 'purchase' | 'refund' | 'lead' | 'qualify_lead' | 'close_convert_lead' | 'disqualify_lead' | 'complete_registration' | 'subscribe' | 'start_trial' | 'app_install' | 'app_launch' | 'contact' | 'schedule' | 'donate' | 'submit_application' | 'custom';
29
+ /**
30
+ * Identifier type that the event's content_ids field should be matched against for items in this catalog. For example, 'gtin' means content_ids values are Global Trade Item Numbers, 'sku' means retailer SKUs. Omit when using a custom identifier scheme not listed in the enum.
31
+ */
32
+ export type ContentIDType = 'sku' | 'gtin' | 'offering_id' | 'job_id' | 'hotel_id' | 'flight_id' | 'vehicle_id' | 'listing_id' | 'store_id' | 'program_id' | 'destination_id' | 'app_id';
13
33
  /**
14
34
  * Metro area classification system (e.g., 'nielsen_dma', 'uk_itl2')
15
35
  */
@@ -22,6 +42,37 @@ export type PostalCodeSystem = 'us_zip' | 'us_zip_plus_four' | 'gb_outward' | 'g
22
42
  * Days of the week for daypart targeting
23
43
  */
24
44
  export type DayOfWeek = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
45
+ /**
46
+ * Frequency capping settings for package-level application. Two types of frequency control can be used independently or together: suppress enforces a cooldown between consecutive exposures; max_impressions + per + window caps total exposures per entity in a time window. When both suppress and max_impressions are set, an impression is delivered only if both constraints permit it (AND semantics). At least one of suppress, suppress_minutes, or max_impressions must be set.
47
+ */
48
+ export type FrequencyCap = {
49
+ [k: string]: unknown | undefined;
50
+ } & {
51
+ /**
52
+ * Cooldown period between consecutive exposures to the same entity. Prevents back-to-back ad delivery (e.g. {"interval": 60, "unit": "minutes"} for a 1-hour cooldown). Preferred over suppress_minutes.
53
+ */
54
+ suppress?: Duration;
55
+ /**
56
+ * Deprecated — use suppress instead. Cooldown period in minutes between consecutive exposures to the same entity (e.g. 60 for a 1-hour cooldown).
57
+ */
58
+ suppress_minutes?: number;
59
+ /**
60
+ * Maximum number of impressions per entity per window. For duration windows, implementations typically use a rolling window; 'campaign' applies a fixed cap across the full flight.
61
+ */
62
+ max_impressions?: number;
63
+ /**
64
+ * Entity granularity for impression counting. Required when max_impressions is set.
65
+ */
66
+ per?: ReachUnit;
67
+ /**
68
+ * Time window for the max_impressions cap (e.g. {"interval": 7, "unit": "days"} or {"interval": 1, "unit": "campaign"} for the full flight). Required when max_impressions is set.
69
+ */
70
+ window?: Duration;
71
+ };
72
+ /**
73
+ * Unit of measurement for reach and audience size metrics. Different channels and measurement providers count reach in fundamentally different units, making cross-channel comparison impossible without declaring the unit.
74
+ */
75
+ export type ReachUnit = 'individuals' | 'households' | 'devices' | 'accounts' | 'cookies' | 'custom';
25
76
  /**
26
77
  * Methods for verifying user age for compliance. Does not include 'inferred' as it is not accepted for regulatory compliance.
27
78
  */
@@ -30,15 +81,29 @@ export type AgeVerificationMethod = 'facial_age_estimation' | 'id_document' | 'd
30
81
  * Operating system platforms for device targeting. Browser values from Sec-CH-UA-Platform standard, extended for CTV.
31
82
  */
32
83
  export type DevicePlatform = 'ios' | 'android' | 'windows' | 'macos' | 'linux' | 'chromeos' | 'tvos' | 'tizen' | 'webos' | 'fire_os' | 'roku_os' | 'unknown';
84
+ /**
85
+ * Device form factor categories for targeting and reporting. Complements device-platform (operating system) with hardware classification. OpenRTB mapping: 1 (Mobile/Tablet General) → mobile, 2 (PC) → desktop, 4 (Phone) → mobile, 5 (Tablet) → tablet, 6 (Connected Device) → ctv, 7 (Set Top Box) → ctv. DOOH inventory uses dooh.
86
+ */
87
+ export type DeviceType = 'desktop' | 'mobile' | 'tablet' | 'ctv' | 'dooh' | 'unknown';
33
88
  /**
34
89
  * A single optimization target for a package. Packages accept an array of optimization_goals. When multiple goals are present, priority determines which the seller focuses on — 1 is highest priority (primary goal); higher numbers are secondary. Duplicate priority values result in undefined seller behavior.
35
90
  */
36
91
  export type OptimizationGoal = {
37
92
  kind: 'metric';
38
93
  /**
39
- * Seller-native metric to optimize for. Delivery metrics: clicks (link clicks, swipe-throughs, CTA taps that navigate away), views (viewable impressions), completed_views (video/audio completions — see view_duration_seconds). Duration/score metrics: viewed_seconds (time in view per impression), attention_seconds (attention time per impression), attention_score (vendor-specific attention score). Audience action metrics: engagements (any direct interaction with the ad unit beyond viewing — social reactions/comments/shares, story/unit opens, interactive overlay taps, companion banner interactions on audio and CTV), follows (new followers, page likes, artist/podcast/channel subscribes), saves (saves, bookmarks, playlist adds, pins — signals of intent to return), profile_visits (visits to the brand's in-platform page — profile, artist page, channel, or storefront. Does not include external website clicks, which are covered by 'clicks').
94
+ * Seller-native metric to optimize for. Delivery metrics: clicks (link clicks, swipe-throughs, CTA taps that navigate away), views (viewable impressions), completed_views (video/audio completions — see view_duration_seconds), reach (unique audience reach — see reach_unit and target_frequency). Duration/score metrics: viewed_seconds (time in view per impression), attention_seconds (attention time per impression), attention_score (vendor-specific attention score). Audience action metrics: engagements (any direct interaction with the ad unit beyond viewing — social reactions/comments/shares, story/unit opens, interactive overlay taps, companion banner interactions on audio and CTV), follows (new followers, page likes, artist/podcast/channel subscribes), saves (saves, bookmarks, playlist adds, pins — signals of intent to return), profile_visits (visits to the brand's in-platform page — profile, artist page, channel, or storefront. Does not include external website clicks, which are covered by 'clicks').
40
95
  */
41
- metric: 'clicks' | 'views' | 'completed_views' | 'viewed_seconds' | 'attention_seconds' | 'attention_score' | 'engagements' | 'follows' | 'saves' | 'profile_visits';
96
+ metric: 'clicks' | 'views' | 'completed_views' | 'viewed_seconds' | 'attention_seconds' | 'attention_score' | 'engagements' | 'follows' | 'saves' | 'profile_visits' | 'reach';
97
+ /**
98
+ * Unit for reach measurement. Required when metric is 'reach'. Must be a value declared in the product's metric_optimization.supported_reach_units.
99
+ */
100
+ reach_unit?: ReachUnit;
101
+ /**
102
+ * Target frequency band for reach optimization. Only applicable when metric is 'reach'. Frames frequency as an optimization signal: the seller should treat impressions toward entities already within the [min, max] band as lower-value, and impressions toward unreached entities as higher-value. This shifts budget toward fresh reach rather than re-reaching known users. When omitted, the seller maximizes unique reach without a frequency constraint. A hard cap can still be layered via targeting_overlay.frequency_cap if a ceiling is needed.
103
+ */
104
+ target_frequency?: {
105
+ [k: string]: unknown | undefined;
106
+ };
42
107
  /**
43
108
  * Minimum video view duration in seconds that qualifies as a completed_view for this goal. Only applicable when metric is 'completed_views'. When omitted, the seller uses their platform default (typically 2–15 seconds). Common values: 2 (Snap/LinkedIn default), 6 (TikTok), 15 (Snap 15-second views, Meta ThruPlay). Sellers declare which durations they support in metric_optimization.supported_view_durations. Sellers must reject goals with unsupported values — silent rounding would create measurement discrepancies.
44
109
  */
@@ -110,23 +175,19 @@ export type OptimizationGoal = {
110
175
  */
111
176
  attribution_window?: {
112
177
  /**
113
- * Click-through attribution window (e.g. '7d', '28d', '30d')
178
+ * Post-click attribution window. Conversions within this duration after a click are attributed to the ad (e.g. {"interval": 7, "unit": "days"}).
114
179
  */
115
- click_through: string;
180
+ post_click: Duration;
116
181
  /**
117
- * View-through attribution window (e.g. '1d', '7d')
182
+ * Post-view attribution window. Conversions within this duration after an ad impression (without click) are attributed to the ad (e.g. {"interval": 1, "unit": "days"}).
118
183
  */
119
- view_through?: string;
184
+ post_view?: Duration;
120
185
  };
121
186
  /**
122
187
  * Relative priority among all optimization goals on this package. 1 = highest priority (primary goal); higher numbers are lower priority (secondary signals). When omitted, sellers may use array position as priority.
123
188
  */
124
189
  priority?: number;
125
190
  };
126
- /**
127
- * Event type to include from this source (e.g., purchase, lead, app_install, refund)
128
- */
129
- export type EventType = 'page_view' | 'view_content' | 'select_content' | 'select_item' | 'search' | 'share' | 'add_to_cart' | 'remove_from_cart' | 'viewed_cart' | 'add_to_wishlist' | 'initiate_checkout' | 'add_payment_info' | 'purchase' | 'refund' | 'lead' | 'qualify_lead' | 'close_convert_lead' | 'disqualify_lead' | 'complete_registration' | 'subscribe' | 'start_trial' | 'app_install' | 'app_launch' | 'contact' | 'schedule' | 'donate' | 'submit_application' | 'custom';
130
191
  /**
131
192
  * Represents a purchased advertising campaign
132
193
  */
@@ -136,7 +197,7 @@ export interface MediaBuy {
136
197
  */
137
198
  media_buy_id: string;
138
199
  /**
139
- * Buyer's reference identifier for this media buy
200
+ * Buyer's reference identifier for this media buy. Sellers SHOULD deduplicate requests with the same buyer_ref and account, returning the existing media buy rather than creating a duplicate.
140
201
  */
141
202
  buyer_ref?: string;
142
203
  /**
@@ -145,6 +206,10 @@ export interface MediaBuy {
145
206
  buyer_campaign_ref?: string;
146
207
  account?: Account;
147
208
  status: MediaBuyStatus;
209
+ /**
210
+ * Reason provided by the seller when status is 'rejected'. Present only when status is 'rejected'.
211
+ */
212
+ rejection_reason?: string;
148
213
  /**
149
214
  * Total budget amount
150
215
  */
@@ -266,7 +331,7 @@ export interface Package {
266
331
  */
267
332
  package_id: string;
268
333
  /**
269
- * Buyer's reference identifier for this package
334
+ * Buyer's reference identifier for this package. Sellers SHOULD deduplicate requests with the same buyer_ref within a media buy, returning the existing package rather than creating a duplicate.
270
335
  */
271
336
  buyer_ref?: string;
272
337
  /**
@@ -290,6 +355,14 @@ export interface Package {
290
355
  * Impression goal for this package
291
356
  */
292
357
  impressions?: number;
358
+ /**
359
+ * Catalogs this package promotes. Each catalog MUST have a distinct type (e.g., one product catalog, one store catalog). This constraint is enforced at the application level — sellers MUST reject requests containing multiple catalogs of the same type with a validation_error. Echoed from the create_media_buy request.
360
+ */
361
+ catalogs?: Catalog[];
362
+ /**
363
+ * Format IDs active for this package. Echoed from the create_media_buy request; omitted means all formats for the product are active.
364
+ */
365
+ format_ids?: FormatID[];
293
366
  targeting_overlay?: TargetingOverlay;
294
367
  /**
295
368
  * Creative assets assigned to this package
@@ -310,7 +383,135 @@ export interface Package {
310
383
  ext?: ExtensionObject;
311
384
  }
312
385
  /**
313
- * Optional restriction overlays for media buys. Most targeting should be expressed in the brief and handled by the publisher. These fields are for functional restrictions: geographic (RCT testing, regulatory compliance), age verification (alcohol, gambling), device platform (app compatibility), and language (localization).
386
+ * A typed data feed. Catalogs carry the items, locations, stock levels, or pricing that publishers use to render ads. They can be synced to a platform via sync_catalogs (managed lifecycle with approval), provided inline, or fetched from an external URL. The catalog type determines the item schema and can be structural (offering, product, inventory, store, promotion) or vertical-specific (hotel, flight, job, vehicle, real_estate, education, destination, app). Selectors (ids, tags, category, query) filter items regardless of sourcing method.
387
+ */
388
+ export interface Catalog {
389
+ /**
390
+ * Buyer's identifier for this catalog. Required when syncing via sync_catalogs. When used in creatives, references a previously synced catalog on the account.
391
+ */
392
+ catalog_id?: string;
393
+ /**
394
+ * Human-readable name for this catalog (e.g., 'Summer Products 2025', 'Amsterdam Store Locations').
395
+ */
396
+ name?: string;
397
+ type: CatalogType;
398
+ /**
399
+ * URL to an external catalog feed. The platform fetches and resolves items from this URL. For offering-type catalogs, the feed contains an array of Offering objects. For other types, the feed format is determined by feed_format. When omitted with type 'product', the platform uses its synced copy of the brand's product catalog.
400
+ */
401
+ url?: string;
402
+ feed_format?: FeedFormat;
403
+ update_frequency?: UpdateFrequency;
404
+ /**
405
+ * Inline catalog data. The item schema depends on the catalog type: Offering objects for 'offering', StoreItem for 'store', HotelItem for 'hotel', FlightItem for 'flight', JobItem for 'job', VehicleItem for 'vehicle', RealEstateItem for 'real_estate', EducationItem for 'education', DestinationItem for 'destination', AppItem for 'app', or freeform objects for 'product', 'inventory', and 'promotion'. Mutually exclusive with url — provide one or the other, not both. Implementations should validate items against the type-specific schema.
406
+ */
407
+ items?: {}[];
408
+ /**
409
+ * Filter catalog to specific item IDs. For offering-type catalogs, these are offering_id values. For product-type catalogs, these are SKU identifiers.
410
+ */
411
+ ids?: string[];
412
+ /**
413
+ * Filter product-type catalogs by GTIN identifiers for cross-retailer catalog matching. Accepts standard GTIN formats (GTIN-8, UPC-A/GTIN-12, EAN-13/GTIN-13, GTIN-14). Only applicable when type is 'product'.
414
+ */
415
+ gtins?: string[];
416
+ /**
417
+ * Filter catalog to items with these tags. Tags are matched using OR logic — items matching any tag are included.
418
+ */
419
+ tags?: string[];
420
+ /**
421
+ * Filter catalog to items in this category (e.g., 'beverages/soft-drinks', 'chef-positions').
422
+ */
423
+ category?: string;
424
+ /**
425
+ * Natural language filter for catalog items (e.g., 'all pasta sauces under $5', 'amsterdam vacancies').
426
+ */
427
+ query?: string;
428
+ /**
429
+ * Event types that represent conversions for items in this catalog. Declares what events the platform should attribute to catalog items — e.g., a job catalog converts via submit_application, a product catalog via purchase. The event's content_ids field carries the item IDs that connect back to catalog items. Use content_id_type to declare what identifier type content_ids values represent.
430
+ */
431
+ conversion_events?: EventType[];
432
+ content_id_type?: ContentIDType;
433
+ /**
434
+ * Declarative normalization rules for external feeds. Maps non-standard feed field names, date formats, price encodings, and image URLs to the AdCP catalog item schema. Applied during sync_catalogs ingestion. Supports field renames, named transforms (date, divide, boolean, split), static literal injection, and assignment of image URLs to typed asset pools.
435
+ */
436
+ feed_field_mappings?: CatalogFieldMapping[];
437
+ }
438
+ /**
439
+ * Declares how a field in an external feed maps to the AdCP catalog item schema. Used in sync_catalogs feed_field_mappings to normalize non-AdCP feeds (Google Merchant Center, LinkedIn Jobs XML, hotel XML, etc.) to the standard catalog item schema without requiring the buyer to preprocess every feed. Multiple mappings can assemble a nested object via dot notation (e.g., separate mappings for price.amount and price.currency).
440
+ */
441
+ export interface CatalogFieldMapping {
442
+ /**
443
+ * Field name in the external feed record. Omit when injecting a static literal value (use the value property instead).
444
+ */
445
+ feed_field?: string;
446
+ /**
447
+ * Target field on the catalog item schema, using dot notation for nested fields (e.g., 'name', 'price.amount', 'location.city'). Mutually exclusive with asset_group_id.
448
+ */
449
+ catalog_field?: string;
450
+ /**
451
+ * Places the feed field value (a URL) into a typed asset pool on the catalog item's assets array. The value is wrapped as an image or video asset in a group with this ID. Use standard group IDs: 'images_landscape', 'images_vertical', 'images_square', 'logo', 'video'. Mutually exclusive with catalog_field.
452
+ */
453
+ asset_group_id?: string;
454
+ /**
455
+ * Static literal value to inject into catalog_field for every item, regardless of what the feed contains. Mutually exclusive with feed_field. Useful for fields the feed omits (e.g., currency when price is always USD, or a constant category value).
456
+ */
457
+ value?: {
458
+ [k: string]: unknown | undefined;
459
+ };
460
+ /**
461
+ * Named transform to apply to the feed field value before writing to the catalog schema. See transform-specific parameters (format, timezone, by, separator).
462
+ */
463
+ transform?: 'date' | 'divide' | 'boolean' | 'split';
464
+ /**
465
+ * For transform 'date': the input date format string (e.g., 'YYYYMMDD', 'MM/DD/YYYY', 'DD-MM-YYYY'). Output is always ISO 8601 (e.g., '2025-03-01'). Uses Unicode date pattern tokens.
466
+ */
467
+ format?: string;
468
+ /**
469
+ * For transform 'date': the timezone of the input value. IANA timezone identifier (e.g., 'UTC', 'America/New_York', 'Europe/Amsterdam'). Defaults to UTC when omitted.
470
+ */
471
+ timezone?: string;
472
+ /**
473
+ * For transform 'divide': the divisor to apply (e.g., 100 to convert integer cents to decimal dollars).
474
+ */
475
+ by?: number;
476
+ /**
477
+ * For transform 'split': the separator character or string to split on. Defaults to ','.
478
+ */
479
+ separator?: string;
480
+ /**
481
+ * Fallback value to use when feed_field is absent, null, or empty. Applied after any transform would have been applied. Allows optional feed fields to have a guaranteed baseline value.
482
+ */
483
+ default?: {
484
+ [k: string]: unknown | undefined;
485
+ };
486
+ ext?: ExtensionObject;
487
+ }
488
+ /**
489
+ * Structured format identifier with agent URL and format name. Can reference: (1) a concrete format with fixed dimensions (id only), (2) a template format without parameters (id only), or (3) a template format with parameters (id + dimensions/duration). Template formats accept parameters in format_id while concrete formats have fixed dimensions in their definition. Parameterized format IDs create unique, specific format variants.
490
+ */
491
+ export interface FormatID {
492
+ /**
493
+ * URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)
494
+ */
495
+ agent_url: string;
496
+ /**
497
+ * Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant.
498
+ */
499
+ id: string;
500
+ /**
501
+ * Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.
502
+ */
503
+ width?: number;
504
+ /**
505
+ * Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.
506
+ */
507
+ height?: number;
508
+ /**
509
+ * Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters.
510
+ */
511
+ duration_ms?: number;
512
+ }
513
+ /**
514
+ * Optional restriction overlays for media buys. Most targeting should be expressed in the brief and handled by the publisher. These fields are for functional restrictions: geographic (RCT testing, regulatory compliance, proximity targeting), age verification (alcohol, gambling), device platform (app compatibility), language (localization), and keyword targeting (search/retail media).
314
515
  */
315
516
  export interface TargetingOverlay {
316
517
  /**
@@ -412,6 +613,14 @@ export interface TargetingOverlay {
412
613
  * Restrict to specific platforms. Use for technical compatibility (app only works on iOS). Values from Sec-CH-UA-Platform standard, extended for CTV.
413
614
  */
414
615
  device_platform?: DevicePlatform[];
616
+ /**
617
+ * Restrict to specific device form factors. Use for campaigns targeting hardware categories rather than operating systems (e.g., mobile-only promotions, CTV campaigns).
618
+ */
619
+ device_type?: DeviceType[];
620
+ /**
621
+ * Exclude specific device form factors from delivery (e.g., exclude CTV for app-install campaigns).
622
+ */
623
+ device_type_exclude?: DeviceType[];
415
624
  /**
416
625
  * Target users within store catchment areas from a synced store catalog. Each entry references a store-type catalog and optionally narrows to specific stores or catchment zones.
417
626
  */
@@ -429,10 +638,46 @@ export interface TargetingOverlay {
429
638
  */
430
639
  catchment_ids?: string[];
431
640
  }[];
641
+ /**
642
+ * Target users within travel time, distance, or a custom boundary around arbitrary geographic points. Multiple entries use OR semantics — a user within range of any listed point is eligible. For campaigns targeting 10+ locations, consider using store_catchments with a location catalog instead. Seller must declare support in get_adcp_capabilities.
643
+ */
644
+ geo_proximity?: {
645
+ [k: string]: unknown | undefined;
646
+ }[];
432
647
  /**
433
648
  * Restrict to users with specific language preferences. ISO 639-1 codes (e.g., 'en', 'es', 'fr').
434
649
  */
435
650
  language?: string[];
651
+ /**
652
+ * Keyword targeting for search and retail media platforms. Restricts delivery to queries matching the specified keywords. Each keyword is identified by the tuple (keyword, match_type) — the same keyword string with different match types are distinct targets. Sellers SHOULD reject duplicate (keyword, match_type) pairs within a single request. Seller must declare support in get_adcp_capabilities.
653
+ */
654
+ keyword_targets?: {
655
+ /**
656
+ * The keyword to target
657
+ */
658
+ keyword: string;
659
+ /**
660
+ * Match type: broad matches related queries, phrase matches queries containing the keyword phrase, exact matches the query exactly
661
+ */
662
+ match_type: 'broad' | 'phrase' | 'exact';
663
+ /**
664
+ * Per-keyword bid price, denominated in the same currency as the package's pricing option. Overrides the package-level bid_price for this keyword. Inherits the max_bid interpretation from the pricing option: when max_bid is true, this is the keyword's bid ceiling; when false, this is the exact bid. If omitted, the package bid_price applies.
665
+ */
666
+ bid_price?: number;
667
+ }[];
668
+ /**
669
+ * Keywords to exclude from delivery. Queries matching these keywords will not trigger the ad. Each negative keyword is identified by the tuple (keyword, match_type). Seller must declare support in get_adcp_capabilities.
670
+ */
671
+ negative_keywords?: {
672
+ /**
673
+ * The keyword to exclude
674
+ */
675
+ keyword: string;
676
+ /**
677
+ * Match type for exclusion
678
+ */
679
+ match_type: 'broad' | 'phrase' | 'exact';
680
+ }[];
436
681
  }
437
682
  /**
438
683
  * A time window for daypart targeting. Specifies days of week and an hour range. start_hour is inclusive, end_hour is exclusive (e.g., 6-10 = 6:00am to 10:00am). Follows the Google Ads AdScheduleInfo / DV360 DayPartTargeting pattern.
@@ -456,13 +701,17 @@ export interface DaypartTarget {
456
701
  label?: string;
457
702
  }
458
703
  /**
459
- * Frequency capping settings for package-level application
704
+ * A time duration expressed as an interval and unit. Used for frequency cap windows, attribution windows, reach optimization windows, and other time-based settings. When unit is 'campaign', interval must be 1 — the window spans the full campaign flight.
460
705
  */
461
- export interface FrequencyCap {
706
+ export interface Duration {
707
+ /**
708
+ * Number of time units. Must be 1 when unit is 'campaign'.
709
+ */
710
+ interval: number;
462
711
  /**
463
- * Minutes to suppress after impression
712
+ * Time unit. 'campaign' spans the full campaign flight.
464
713
  */
465
- suppress_minutes: number;
714
+ unit: 'minutes' | 'hours' | 'days' | 'campaign';
466
715
  }
467
716
  /**
468
717
  * Reference to a property list for targeting specific properties within this product. The package runs on the intersection of the product's publisher_properties and this list. Sellers SHOULD return a validation error if the product has property_targeting_allowed: false.
@@ -490,7 +739,7 @@ export interface CreativeAssignment {
490
739
  */
491
740
  creative_id: string;
492
741
  /**
493
- * Delivery weight for this creative
742
+ * Relative delivery weight for this creative (0–100). When multiple creatives are assigned to the same package, weights determine impression distribution proportionally — a creative with weight 2 gets twice the delivery of weight 1. When omitted, the creative receives equal rotation with other unweighted creatives. A weight of 0 means the creative is assigned but paused (receives no delivery).
494
743
  */
495
744
  weight?: number;
496
745
  /**
@@ -499,50 +748,9 @@ export interface CreativeAssignment {
499
748
  placement_ids?: string[];
500
749
  }
501
750
  /**
502
- * Structured format identifier with agent URL and format name. Can reference: (1) a concrete format with fixed dimensions (id only), (2) a template format without parameters (id only), or (3) a template format with parameters (id + dimensions/duration). Template formats accept parameters in format_id while concrete formats have fixed dimensions in their definition. Parameterized format IDs create unique, specific format variants.
503
- */
504
- export interface FormatID {
505
- /**
506
- * URL of the agent that defines this format (e.g., 'https://creatives.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats)
507
- */
508
- agent_url: string;
509
- /**
510
- * Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant.
511
- */
512
- id: string;
513
- /**
514
- * Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.
515
- */
516
- width?: number;
517
- /**
518
- * Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.
519
- */
520
- height?: number;
521
- /**
522
- * Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters.
523
- */
524
- duration_ms?: number;
525
- }
526
- /**
527
- * Catalog type. Structural types: 'offering' (AdCP Offering objects), 'product' (ecommerce entries), 'inventory' (stock per location), 'store' (physical locations), 'promotion' (deals and pricing). Vertical types: 'hotel', 'flight', 'job', 'vehicle', 'real_estate', 'education', 'destination', 'app' — each with an industry-specific item schema.
528
- */
529
- export type CatalogType = 'offering' | 'product' | 'inventory' | 'store' | 'promotion' | 'hotel' | 'flight' | 'job' | 'vehicle' | 'real_estate' | 'education' | 'destination' | 'app';
530
- /**
531
- * Format of the external feed at url. Required when url points to a non-AdCP feed (e.g., Google Merchant Center XML, Meta Product Catalog). Omit for offering-type catalogs where the feed is native AdCP JSON.
532
- */
533
- export type FeedFormat = 'google_merchant_center' | 'facebook_catalog' | 'shopify' | 'linkedin_jobs' | 'custom';
534
- /**
535
- * How often the platform should re-fetch the feed from url. Only applicable when url is provided. Platforms may use this as a hint for polling schedules.
751
+ * IPTC-aligned classification of AI involvement in producing this content
536
752
  */
537
- export type UpdateFrequency = 'realtime' | 'hourly' | 'daily' | 'weekly';
538
- /**
539
- * Identifier type that the event's content_ids field should be matched against for items in this catalog. For example, 'gtin' means content_ids values are Global Trade Item Numbers, 'sku' means retailer SKUs. Omit when using a custom identifier scheme not listed in the enum.
540
- */
541
- export type ContentIDType = 'sku' | 'gtin' | 'offering_id' | 'job_id' | 'hotel_id' | 'flight_id' | 'vehicle_id' | 'listing_id' | 'store_id' | 'program_id' | 'destination_id' | 'app_id';
542
- /**
543
- * JavaScript module type
544
- */
545
- export type JavaScriptModuleType = 'esm' | 'commonjs' | 'script';
753
+ export type DigitalSourceType = 'digital_capture' | 'digital_creation' | 'trained_algorithmic_media' | 'composite_with_trained_algorithmic_media' | 'algorithmic_media' | 'composite_capture' | 'composite_synthetic' | 'human_edits' | 'data_driven_media';
546
754
  /**
547
755
  * VAST (Video Ad Serving Template) tag for third-party video ad serving
548
756
  */
@@ -576,6 +784,7 @@ export type VASTAsset = {
576
784
  * URL to audio description track for visually impaired users
577
785
  */
578
786
  audio_description_url?: string;
787
+ provenance?: Provenance;
579
788
  } | {
580
789
  /**
581
790
  * Discriminator indicating VAST is delivered as inline XML content
@@ -606,6 +815,7 @@ export type VASTAsset = {
606
815
  * URL to audio description track for visually impaired users
607
816
  */
608
817
  audio_description_url?: string;
818
+ provenance?: Provenance;
609
819
  };
610
820
  /**
611
821
  * VAST specification version
@@ -615,6 +825,30 @@ export type VASTVersion = '2.0' | '3.0' | '4.0' | '4.1' | '4.2';
615
825
  * Standard VAST tracking events for video ad playback and interaction
616
826
  */
617
827
  export type VASTTrackingEvent = 'start' | 'firstQuartile' | 'midpoint' | 'thirdQuartile' | 'complete' | 'impression' | 'click' | 'pause' | 'resume' | 'skip' | 'mute' | 'unmute' | 'fullscreen' | 'exitFullscreen' | 'playerExpand' | 'playerCollapse';
828
+ /**
829
+ * Type of URL asset: 'clickthrough' for user click destination (landing page), 'tracker_pixel' for impression/event tracking via HTTP request (fires GET, expects pixel/204 response), 'tracker_script' for measurement SDKs that must load as <script> tag (OMID verification, native event trackers using method:2)
830
+ */
831
+ export type URLAssetType = 'clickthrough' | 'tracker_pixel' | 'tracker_script';
832
+ /**
833
+ * JavaScript module type
834
+ */
835
+ export type JavaScriptModuleType = 'esm' | 'commonjs' | 'script';
836
+ /**
837
+ * HTTP method
838
+ */
839
+ export type HTTPMethod = 'GET' | 'POST';
840
+ /**
841
+ * Standardized macro placeholders for dynamic value substitution in creative tracking URLs. Macros are replaced with actual values at impression time. See docs/creative/universal-macros.mdx for detailed documentation.
842
+ */
843
+ export type UniversalMacro = 'MEDIA_BUY_ID' | 'PACKAGE_ID' | 'CREATIVE_ID' | 'CACHEBUSTER' | 'TIMESTAMP' | 'CLICK_URL' | 'GDPR' | 'GDPR_CONSENT' | 'US_PRIVACY' | 'GPP_STRING' | 'GPP_SID' | 'IP_ADDRESS' | 'LIMIT_AD_TRACKING' | 'DEVICE_TYPE' | 'OS' | 'OS_VERSION' | 'DEVICE_MAKE' | 'DEVICE_MODEL' | 'USER_AGENT' | 'APP_BUNDLE' | 'APP_NAME' | 'COUNTRY' | 'REGION' | 'CITY' | 'ZIP' | 'DMA' | 'LAT' | 'LONG' | 'DEVICE_ID' | 'DEVICE_ID_TYPE' | 'DOMAIN' | 'PAGE_URL' | 'REFERRER' | 'KEYWORDS' | 'PLACEMENT_ID' | 'FOLD_POSITION' | 'AD_WIDTH' | 'AD_HEIGHT' | 'VIDEO_ID' | 'VIDEO_TITLE' | 'VIDEO_DURATION' | 'VIDEO_CATEGORY' | 'CONTENT_GENRE' | 'CONTENT_RATING' | 'PLAYER_WIDTH' | 'PLAYER_HEIGHT' | 'POD_POSITION' | 'POD_SIZE' | 'AD_BREAK_ID' | 'STATION_ID' | 'SHOW_NAME' | 'EPISODE_ID' | 'AUDIO_DURATION' | 'AXEM' | 'CATALOG_ID' | 'SKU' | 'GTIN' | 'OFFERING_ID' | 'JOB_ID' | 'HOTEL_ID' | 'FLIGHT_ID' | 'VEHICLE_ID' | 'LISTING_ID' | 'STORE_ID' | 'PROGRAM_ID' | 'DESTINATION_ID' | 'CREATIVE_VARIANT_ID' | 'APP_ITEM_ID';
844
+ /**
845
+ * Expected content type of webhook response
846
+ */
847
+ export type WebhookResponseType = 'html' | 'json' | 'xml' | 'javascript';
848
+ /**
849
+ * Authentication method
850
+ */
851
+ export type WebhookSecurityMethod = 'hmac_sha256' | 'api_key' | 'none';
618
852
  /**
619
853
  * DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving
620
854
  */
@@ -644,6 +878,7 @@ export type DAASTAsset = {
644
878
  * URL to text transcript of the audio content
645
879
  */
646
880
  transcript_url?: string;
881
+ provenance?: Provenance;
647
882
  } | {
648
883
  /**
649
884
  * Discriminator indicating DAAST is delivered as inline XML content
@@ -670,6 +905,7 @@ export type DAASTAsset = {
670
905
  * URL to text transcript of the audio content
671
906
  */
672
907
  transcript_url?: string;
908
+ provenance?: Provenance;
673
909
  };
674
910
  /**
675
911
  * DAAST specification version
@@ -680,9 +916,21 @@ export type DAASTVersion = '1.0' | '1.1';
680
916
  */
681
917
  export type DAASTTrackingEvent = 'start' | 'firstQuartile' | 'midpoint' | 'thirdQuartile' | 'complete' | 'impression' | 'pause' | 'resume' | 'skip' | 'mute' | 'unmute';
682
918
  /**
683
- * Type of URL asset: 'clickthrough' for user click destination (landing page), 'tracker_pixel' for impression/event tracking via HTTP request (fires GET, expects pixel/204 response), 'tracker_script' for measurement SDKs that must load as <script> tag (OMID verification, native event trackers using method:2)
919
+ * Markdown flavor used. CommonMark for strict compatibility, GFM for tables/task lists/strikethrough.
684
920
  */
685
- export type URLAssetType = 'clickthrough' | 'tracker_pixel' | 'tracker_script';
921
+ export type MarkdownFlavor = 'commonmark' | 'gfm';
922
+ /**
923
+ * Campaign-level creative context as an asset. Carries the creative brief through the manifest so it travels with the creative through regeneration, resizing, and auditing.
924
+ */
925
+ export type BriefAsset = CreativeBrief;
926
+ /**
927
+ * Where the disclosure should appear within the creative. prominent: clearly visible in the main creative area; footer: at the bottom of visual creatives; audio: spoken in audio/video creatives; subtitle: displayed in the subtitle or closed-caption track; overlay: superimposed on video content; end_card: displayed on video end card; pre_roll: spoken or displayed before main content; companion: in companion ad unit alongside primary creative
928
+ */
929
+ export type DisclosurePosition = 'prominent' | 'footer' | 'audio' | 'subtitle' | 'overlay' | 'end_card' | 'pre_roll' | 'companion';
930
+ /**
931
+ * A typed data feed as a creative asset. Carries catalog context (products, stores, jobs, etc.) within the manifest's assets map.
932
+ */
933
+ export type CatalogAsset = Catalog;
686
934
  /**
687
935
  * For generative creatives: set to 'approved' to finalize, 'rejected' to request regeneration with updated assets/message. Omit for non-generative creatives (system will set based on processing state).
688
936
  */
@@ -701,18 +949,14 @@ export interface CreativeAsset {
701
949
  name: string;
702
950
  format_id: FormatID;
703
951
  /**
704
- * Catalogs this creative renders. Each entry satisfies one of the format's catalog_requirements, matched by type. Each catalog can be inline (with items), a reference to a synced catalog (by catalog_id), or a URL to an external feed.
705
- */
706
- catalogs?: Catalog[];
707
- /**
708
- * Assets required by the format, keyed by asset_role
952
+ * Assets required by the format, keyed by asset_id
709
953
  */
710
954
  assets: {
711
955
  /**
712
956
  * This interface was referenced by `undefined`'s JSON-Schema definition
713
- * via the `patternProperty` "^[a-zA-Z0-9_-]+$".
957
+ * via the `patternProperty` "^[a-z0-9_]+$".
714
958
  */
715
- [k: string]: ImageAsset | VideoAsset | AudioAsset | TextAsset | HTMLAsset | CSSAsset | JavaScriptAsset | VASTAsset | DAASTAsset | URLAsset;
959
+ [k: string]: ImageAsset | VideoAsset | AudioAsset | VASTAsset | TextAsset | URLAsset | HTMLAsset | JavaScriptAsset | WebhookAsset | CSSAsset | DAASTAsset | MarkdownAsset | BriefAsset | CatalogAsset;
716
960
  };
717
961
  /**
718
962
  * Preview contexts for generative formats - defines what scenarios to generate previews for
@@ -720,135 +964,33 @@ export interface CreativeAsset {
720
964
  inputs?: {
721
965
  /**
722
966
  * Human-readable name for this preview variant
723
- */
724
- name: string;
725
- /**
726
- * Macro values to apply for this preview
727
- */
728
- macros?: {
729
- [k: string]: string | undefined;
730
- };
731
- /**
732
- * Natural language description of the context for AI-generated content
733
- */
734
- context_description?: string;
735
- }[];
736
- /**
737
- * User-defined tags for organization and searchability
738
- */
739
- tags?: string[];
740
- status?: CreativeStatus;
741
- /**
742
- * Optional delivery weight for creative rotation when uploading via create_media_buy or update_media_buy (0-100). If omitted, platform determines rotation. Only used during upload to media buy - not stored in creative library.
743
- */
744
- weight?: number;
745
- /**
746
- * Optional array of placement IDs where this creative should run when uploading via create_media_buy or update_media_buy. References placement_id values from the product's placements array. If omitted, creative runs on all placements. Only used during upload to media buy - not stored in creative library.
747
- */
748
- placement_ids?: string[];
749
- }
750
- /**
751
- * A typed data feed. Catalogs carry the items, locations, stock levels, or pricing that publishers use to render ads. They can be synced to a platform via sync_catalogs (managed lifecycle with approval), provided inline, or fetched from an external URL. The catalog type determines the item schema and can be structural (offering, product, inventory, store, promotion) or vertical-specific (hotel, flight, job, vehicle, real_estate, education, destination, app). Selectors (ids, tags, category, query) filter items regardless of sourcing method.
752
- */
753
- export interface Catalog {
754
- /**
755
- * Buyer's identifier for this catalog. Required when syncing via sync_catalogs. When used in creatives, references a previously synced catalog on the account.
756
- */
757
- catalog_id?: string;
758
- /**
759
- * Human-readable name for this catalog (e.g., 'Summer Products 2025', 'Amsterdam Store Locations').
760
- */
761
- name?: string;
762
- type: CatalogType;
763
- /**
764
- * URL to an external catalog feed. The platform fetches and resolves items from this URL. For offering-type catalogs, the feed contains an array of Offering objects. For other types, the feed format is determined by feed_format. When omitted with type 'product', the platform uses its synced copy of the brand's product catalog.
765
- */
766
- url?: string;
767
- feed_format?: FeedFormat;
768
- update_frequency?: UpdateFrequency;
769
- /**
770
- * Inline catalog data. The item schema depends on the catalog type: Offering objects for 'offering', StoreItem for 'store', HotelItem for 'hotel', FlightItem for 'flight', JobItem for 'job', VehicleItem for 'vehicle', RealEstateItem for 'real_estate', EducationItem for 'education', DestinationItem for 'destination', AppItem for 'app', or freeform objects for 'product', 'inventory', and 'promotion'. Mutually exclusive with url — provide one or the other, not both. Implementations should validate items against the type-specific schema.
771
- */
772
- items?: {}[];
773
- /**
774
- * Filter catalog to specific item IDs. For offering-type catalogs, these are offering_id values. For product-type catalogs, these are SKU identifiers.
775
- */
776
- ids?: string[];
777
- /**
778
- * Filter product-type catalogs by GTIN identifiers for cross-retailer catalog matching. Accepts standard GTIN formats (GTIN-8, UPC-A/GTIN-12, EAN-13/GTIN-13, GTIN-14). Only applicable when type is 'product'.
779
- */
780
- gtins?: string[];
781
- /**
782
- * Filter catalog to items with these tags. Tags are matched using OR logic — items matching any tag are included.
783
- */
784
- tags?: string[];
785
- /**
786
- * Filter catalog to items in this category (e.g., 'beverages/soft-drinks', 'chef-positions').
787
- */
788
- category?: string;
789
- /**
790
- * Natural language filter for catalog items (e.g., 'all pasta sauces under $5', 'amsterdam vacancies').
791
- */
792
- query?: string;
793
- /**
794
- * Event types that represent conversions for items in this catalog. Declares what events the platform should attribute to catalog items — e.g., a job catalog converts via submit_application, a product catalog via purchase. The event's content_ids field carries the item IDs that connect back to catalog items. Use content_id_type to declare what identifier type content_ids values represent.
795
- */
796
- conversion_events?: EventType[];
797
- content_id_type?: ContentIDType;
798
- /**
799
- * Declarative normalization rules for external feeds. Maps non-standard feed field names, date formats, price encodings, and image URLs to the AdCP catalog item schema. Applied during sync_catalogs ingestion. Supports field renames, named transforms (date, divide, boolean, split), static literal injection, and assignment of image URLs to typed asset pools.
800
- */
801
- feed_field_mappings?: CatalogFieldMapping[];
802
- }
803
- /**
804
- * Declares how a field in an external feed maps to the AdCP catalog item schema. Used in sync_catalogs feed_field_mappings to normalize non-AdCP feeds (Google Merchant Center, LinkedIn Jobs XML, hotel XML, etc.) to the standard catalog item schema without requiring the buyer to preprocess every feed. Multiple mappings can assemble a nested object via dot notation (e.g., separate mappings for price.amount and price.currency).
805
- */
806
- export interface CatalogFieldMapping {
807
- /**
808
- * Field name in the external feed record. Omit when injecting a static literal value (use the value property instead).
809
- */
810
- feed_field?: string;
811
- /**
812
- * Target field on the catalog item schema, using dot notation for nested fields (e.g., 'name', 'price.amount', 'location.city'). Mutually exclusive with asset_group_id.
813
- */
814
- catalog_field?: string;
815
- /**
816
- * Places the feed field value (a URL) into a typed asset pool on the catalog item's assets array. The value is wrapped as an image or video asset in a group with this ID. Use standard group IDs: 'images_landscape', 'images_vertical', 'images_square', 'logo', 'video'. Mutually exclusive with catalog_field.
817
- */
818
- asset_group_id?: string;
819
- /**
820
- * Static literal value to inject into catalog_field for every item, regardless of what the feed contains. Mutually exclusive with feed_field. Useful for fields the feed omits (e.g., currency when price is always USD, or a constant category value).
821
- */
822
- value?: {
823
- [k: string]: unknown | undefined;
824
- };
825
- /**
826
- * Named transform to apply to the feed field value before writing to the catalog schema. See transform-specific parameters (format, timezone, by, separator).
827
- */
828
- transform?: 'date' | 'divide' | 'boolean' | 'split';
829
- /**
830
- * For transform 'date': the input date format string (e.g., 'YYYYMMDD', 'MM/DD/YYYY', 'DD-MM-YYYY'). Output is always ISO 8601 (e.g., '2025-03-01'). Uses Unicode date pattern tokens.
831
- */
832
- format?: string;
833
- /**
834
- * For transform 'date': the timezone of the input value. IANA timezone identifier (e.g., 'UTC', 'America/New_York', 'Europe/Amsterdam'). Defaults to UTC when omitted.
835
- */
836
- timezone?: string;
967
+ */
968
+ name: string;
969
+ /**
970
+ * Macro values to apply for this preview
971
+ */
972
+ macros?: {
973
+ [k: string]: string | undefined;
974
+ };
975
+ /**
976
+ * Natural language description of the context for AI-generated content
977
+ */
978
+ context_description?: string;
979
+ }[];
837
980
  /**
838
- * For transform 'divide': the divisor to apply (e.g., 100 to convert integer cents to decimal dollars).
981
+ * User-defined tags for organization and searchability
839
982
  */
840
- by?: number;
983
+ tags?: string[];
984
+ status?: CreativeStatus;
841
985
  /**
842
- * For transform 'split': the separator character or string to split on. Defaults to ','.
986
+ * Optional delivery weight for creative rotation when uploading via create_media_buy or update_media_buy (0-100). If omitted, platform determines rotation. Only used during upload to media buy - not stored in creative library.
843
987
  */
844
- separator?: string;
988
+ weight?: number;
845
989
  /**
846
- * Fallback value to use when feed_field is absent, null, or empty. Applied after any transform would have been applied. Allows optional feed fields to have a guaranteed baseline value.
990
+ * Optional array of placement IDs where this creative should run when uploading via create_media_buy or update_media_buy. References placement_id values from the product's placements array. If omitted, creative runs on all placements. Only used during upload to media buy - not stored in creative library.
847
991
  */
848
- default?: {
849
- [k: string]: unknown | undefined;
850
- };
851
- ext?: ExtensionObject;
992
+ placement_ids?: string[];
993
+ provenance?: Provenance;
852
994
  }
853
995
  /**
854
996
  * Image asset with URL and dimensions
@@ -874,6 +1016,116 @@ export interface ImageAsset {
874
1016
  * Alternative text for accessibility
875
1017
  */
876
1018
  alt_text?: string;
1019
+ provenance?: Provenance;
1020
+ }
1021
+ /**
1022
+ * Provenance metadata for this asset, overrides manifest-level provenance
1023
+ */
1024
+ export interface Provenance {
1025
+ digital_source_type?: DigitalSourceType;
1026
+ /**
1027
+ * AI system used to generate or modify this content. Aligns with IPTC 2025.1 AI metadata fields and C2PA claim_generator.
1028
+ */
1029
+ ai_tool?: {
1030
+ /**
1031
+ * Name of the AI tool or model (e.g., 'DALL-E 3', 'Stable Diffusion XL', 'Gemini')
1032
+ */
1033
+ name: string;
1034
+ /**
1035
+ * Version identifier for the AI tool or model (e.g., '25.1', '0125', '2.1'). For generative models, use the model version rather than the API version.
1036
+ */
1037
+ version?: string;
1038
+ /**
1039
+ * Organization that provides the AI tool (e.g., 'OpenAI', 'Stability AI', 'Google')
1040
+ */
1041
+ provider?: string;
1042
+ };
1043
+ /**
1044
+ * Level of human involvement in the AI-assisted creation process
1045
+ */
1046
+ human_oversight?: 'none' | 'prompt_only' | 'selected' | 'edited' | 'directed';
1047
+ /**
1048
+ * Party declaring this provenance. Identifies who attached the provenance claim, enabling receiving parties to assess trust.
1049
+ */
1050
+ declared_by?: {
1051
+ /**
1052
+ * URL of the agent or service that declared this provenance
1053
+ */
1054
+ agent_url?: string;
1055
+ /**
1056
+ * Role of the declaring party in the supply chain
1057
+ */
1058
+ role: 'creator' | 'advertiser' | 'agency' | 'platform' | 'tool';
1059
+ };
1060
+ /**
1061
+ * When this content was created or generated (ISO 8601)
1062
+ */
1063
+ created_time?: string;
1064
+ /**
1065
+ * C2PA Content Credentials reference. Links to the cryptographic provenance manifest for this content. Because file-level C2PA bindings break during ad-tech transcoding, this URL reference preserves the chain of provenance through the supply chain.
1066
+ */
1067
+ c2pa?: {
1068
+ /**
1069
+ * URL to the C2PA manifest store for this content
1070
+ */
1071
+ manifest_url: string;
1072
+ };
1073
+ /**
1074
+ * Regulatory disclosure requirements for this content. Indicates whether AI disclosure is required and under which jurisdictions.
1075
+ */
1076
+ disclosure?: {
1077
+ /**
1078
+ * Whether AI disclosure is required for this content based on applicable regulations
1079
+ */
1080
+ required: boolean;
1081
+ /**
1082
+ * Jurisdictions where disclosure obligations apply
1083
+ */
1084
+ jurisdictions?: {
1085
+ /**
1086
+ * ISO 3166-1 alpha-2 country code (e.g., 'US', 'DE', 'CN')
1087
+ */
1088
+ country: string;
1089
+ /**
1090
+ * Sub-national region code (e.g., 'CA' for California, 'BY' for Bavaria)
1091
+ */
1092
+ region?: string;
1093
+ /**
1094
+ * Regulation identifier (e.g., 'eu_ai_act_article_50', 'ca_sb_942', 'cn_deep_synthesis')
1095
+ */
1096
+ regulation: string;
1097
+ /**
1098
+ * Required disclosure label text for this jurisdiction, in the local language
1099
+ */
1100
+ label_text?: string;
1101
+ }[];
1102
+ };
1103
+ /**
1104
+ * Third-party verification or detection results for this content. Multiple services may independently evaluate the same content. Provenance is a claim — verification results attached by the declaring party are supplementary. The enforcing party (e.g., seller/publisher) should run its own verification via get_creative_features or calibrate_content.
1105
+ */
1106
+ verification?: {
1107
+ /**
1108
+ * Name of the verification service (e.g., 'DoubleVerify', 'Hive Moderation', 'Reality Defender')
1109
+ */
1110
+ verified_by: string;
1111
+ /**
1112
+ * When the verification was performed (ISO 8601)
1113
+ */
1114
+ verified_time?: string;
1115
+ /**
1116
+ * Verification outcome
1117
+ */
1118
+ result: 'authentic' | 'ai_generated' | 'ai_modified' | 'inconclusive';
1119
+ /**
1120
+ * Confidence score of the verification result (0.0 to 1.0)
1121
+ */
1122
+ confidence?: number;
1123
+ /**
1124
+ * URL to the full verification report
1125
+ */
1126
+ details_url?: string;
1127
+ }[];
1128
+ ext?: ExtensionObject;
877
1129
  }
878
1130
  /**
879
1131
  * Video asset with URL and technical specifications including audio track properties
@@ -995,6 +1247,7 @@ export interface VideoAsset {
995
1247
  * URL to audio description track for visually impaired users
996
1248
  */
997
1249
  audio_description_url?: string;
1250
+ provenance?: Provenance;
998
1251
  }
999
1252
  /**
1000
1253
  * Audio asset with URL and technical specifications
@@ -1048,6 +1301,7 @@ export interface AudioAsset {
1048
1301
  * URL to text transcript of the audio content
1049
1302
  */
1050
1303
  transcript_url?: string;
1304
+ provenance?: Provenance;
1051
1305
  }
1052
1306
  /**
1053
1307
  * Text content asset
@@ -1061,6 +1315,22 @@ export interface TextAsset {
1061
1315
  * Language code (e.g., 'en', 'es', 'fr')
1062
1316
  */
1063
1317
  language?: string;
1318
+ provenance?: Provenance;
1319
+ }
1320
+ /**
1321
+ * URL reference asset
1322
+ */
1323
+ export interface URLAsset {
1324
+ /**
1325
+ * URL reference
1326
+ */
1327
+ url: string;
1328
+ url_type?: URLAssetType;
1329
+ /**
1330
+ * Description of what this URL points to
1331
+ */
1332
+ description?: string;
1333
+ provenance?: Provenance;
1064
1334
  }
1065
1335
  /**
1066
1336
  * HTML content asset
@@ -1095,19 +1365,7 @@ export interface HTMLAsset {
1095
1365
  */
1096
1366
  screen_reader_tested?: boolean;
1097
1367
  };
1098
- }
1099
- /**
1100
- * CSS stylesheet asset
1101
- */
1102
- export interface CSSAsset {
1103
- /**
1104
- * CSS content
1105
- */
1106
- content: string;
1107
- /**
1108
- * CSS media query context (e.g., 'screen', 'print')
1109
- */
1110
- media?: string;
1368
+ provenance?: Provenance;
1111
1369
  }
1112
1370
  /**
1113
1371
  * JavaScript code asset
@@ -1139,18 +1397,177 @@ export interface JavaScriptAsset {
1139
1397
  */
1140
1398
  screen_reader_tested?: boolean;
1141
1399
  };
1400
+ provenance?: Provenance;
1142
1401
  }
1143
1402
  /**
1144
- * URL reference asset
1403
+ * Webhook for server-side dynamic content rendering (DCO)
1145
1404
  */
1146
- export interface URLAsset {
1405
+ export interface WebhookAsset {
1147
1406
  /**
1148
- * URL reference
1407
+ * Webhook URL to call for dynamic content
1149
1408
  */
1150
1409
  url: string;
1151
- url_type?: URLAssetType;
1410
+ method?: HTTPMethod;
1152
1411
  /**
1153
- * Description of what this URL points to
1412
+ * Maximum time to wait for response in milliseconds
1413
+ */
1414
+ timeout_ms?: number;
1415
+ /**
1416
+ * Universal macros that can be passed to webhook (e.g., DEVICE_TYPE, COUNTRY). See docs/creative/universal-macros.mdx for full list.
1417
+ */
1418
+ supported_macros?: (UniversalMacro | string)[];
1419
+ /**
1420
+ * Universal macros that must be provided for webhook to function
1421
+ */
1422
+ required_macros?: (UniversalMacro | string)[];
1423
+ response_type: WebhookResponseType;
1424
+ /**
1425
+ * Security configuration for webhook calls
1426
+ */
1427
+ security: {
1428
+ method: WebhookSecurityMethod;
1429
+ /**
1430
+ * Header name for HMAC signature (e.g., 'X-Signature')
1431
+ */
1432
+ hmac_header?: string;
1433
+ /**
1434
+ * Header name for API key (e.g., 'X-API-Key')
1435
+ */
1436
+ api_key_header?: string;
1437
+ };
1438
+ provenance?: Provenance;
1439
+ }
1440
+ /**
1441
+ * CSS stylesheet asset
1442
+ */
1443
+ export interface CSSAsset {
1444
+ /**
1445
+ * CSS content
1446
+ */
1447
+ content: string;
1448
+ /**
1449
+ * CSS media query context (e.g., 'screen', 'print')
1450
+ */
1451
+ media?: string;
1452
+ provenance?: Provenance;
1453
+ }
1454
+ /**
1455
+ * Markdown-formatted text content following CommonMark specification
1456
+ */
1457
+ export interface MarkdownAsset {
1458
+ /**
1459
+ * Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions
1460
+ */
1461
+ content: string;
1462
+ /**
1463
+ * Language code (e.g., 'en', 'es', 'fr')
1464
+ */
1465
+ language?: string;
1466
+ markdown_flavor?: MarkdownFlavor;
1467
+ /**
1468
+ * Whether raw HTML blocks are allowed in the markdown. False recommended for security.
1469
+ */
1470
+ allow_raw_html?: boolean;
1471
+ }
1472
+ /**
1473
+ * Campaign-level creative context for AI-powered creative generation. Provides the layer between brand identity (stable across campaigns) and individual creative execution (per-request). A brand has one identity (defined in brand.json) but different creative briefs for each campaign or flight.
1474
+ */
1475
+ export interface CreativeBrief {
1476
+ /**
1477
+ * Campaign or flight name for identification
1478
+ */
1479
+ name: string;
1480
+ /**
1481
+ * Campaign objective that guides creative tone and call-to-action strategy
1482
+ */
1483
+ objective?: 'awareness' | 'consideration' | 'conversion' | 'retention' | 'engagement';
1484
+ /**
1485
+ * Desired tone for this campaign, modulating the brand's base tone (e.g., 'playful and festive', 'premium and aspirational')
1486
+ */
1487
+ tone?: string;
1488
+ /**
1489
+ * Target audience description for this campaign
1490
+ */
1491
+ audience?: string;
1492
+ /**
1493
+ * Creative territory or positioning the campaign should occupy
1494
+ */
1495
+ territory?: string;
1496
+ /**
1497
+ * Messaging framework for the campaign
1498
+ */
1499
+ messaging?: {
1500
+ /**
1501
+ * Primary headline
1502
+ */
1503
+ headline?: string;
1504
+ /**
1505
+ * Supporting tagline or sub-headline
1506
+ */
1507
+ tagline?: string;
1508
+ /**
1509
+ * Call-to-action text
1510
+ */
1511
+ cta?: string;
1512
+ /**
1513
+ * Key messages to communicate in priority order
1514
+ */
1515
+ key_messages?: string[];
1516
+ };
1517
+ /**
1518
+ * Visual and strategic reference materials such as mood boards, product shots, example creatives, and strategy documents
1519
+ */
1520
+ reference_assets?: ReferenceAsset[];
1521
+ /**
1522
+ * Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json.
1523
+ */
1524
+ compliance?: {
1525
+ /**
1526
+ * Disclosures that must appear in creatives for this campaign. Each disclosure specifies the text, where it should appear, and which jurisdictions require it.
1527
+ */
1528
+ required_disclosures?: {
1529
+ /**
1530
+ * The disclosure text that must appear in the creative
1531
+ */
1532
+ text: string;
1533
+ position?: DisclosurePosition;
1534
+ /**
1535
+ * Jurisdictions where this disclosure is required. ISO 3166-1 alpha-2 country codes or ISO 3166-2 subdivision codes (e.g., 'US', 'GB', 'US-NJ', 'CA-QC'). If omitted, the disclosure applies to all jurisdictions in the campaign.
1536
+ */
1537
+ jurisdictions?: string[];
1538
+ /**
1539
+ * The regulation or legal authority requiring this disclosure (e.g., 'SEC Rule 156', 'FCA COBS 4.5', 'FDA 21 CFR 202')
1540
+ */
1541
+ regulation?: string;
1542
+ /**
1543
+ * Minimum display duration in milliseconds. For video/audio disclosures, how long the disclosure must be visible or audible. For static formats, how long the disclosure must remain on screen before any auto-advance.
1544
+ */
1545
+ min_duration_ms?: number;
1546
+ /**
1547
+ * Language of the disclosure text as a BCP 47 language tag (e.g., 'en', 'fr-CA', 'es'). When omitted, the disclosure is assumed to match the creative's language.
1548
+ */
1549
+ language?: string;
1550
+ }[];
1551
+ /**
1552
+ * Claims that must not appear in creatives for this campaign. Creative agents should ensure generated content avoids these claims.
1553
+ */
1554
+ prohibited_claims?: string[];
1555
+ };
1556
+ }
1557
+ /**
1558
+ * A reference asset that provides creative context. Carries visual materials (mood boards, product shots, example creatives) with semantic roles that tell creative agents how to use them.
1559
+ */
1560
+ export interface ReferenceAsset {
1561
+ /**
1562
+ * URL to the reference asset (image, video, or document)
1563
+ */
1564
+ url: string;
1565
+ /**
1566
+ * How the creative agent should use this asset. style_reference: match the visual style; product_shot: include this product; mood_board: overall look and feel; example_creative: example of a similar execution; logo: logo to use; strategy_doc: strategy or planning document for context
1567
+ */
1568
+ role: 'style_reference' | 'product_shot' | 'mood_board' | 'example_creative' | 'logo' | 'strategy_doc';
1569
+ /**
1570
+ * Human-readable description of the asset and how it should inform creative generation
1154
1571
  */
1155
1572
  description?: string;
1156
1573
  }
@@ -1225,10 +1642,6 @@ export type ForecastRangeUnit = 'spend' | 'reach_freq' | 'weekly' | 'daily' | 'c
1225
1642
  * Method used to produce this forecast
1226
1643
  */
1227
1644
  export type ForecastMethod = 'estimate' | 'modeled' | 'guaranteed';
1228
- /**
1229
- * Unit of measurement for reach and audience_size metrics in this forecast. Required for cross-channel forecast comparison.
1230
- */
1231
- export type ReachUnit = 'individuals' | 'households' | 'devices' | 'accounts' | 'cookies' | 'custom';
1232
1645
  /**
1233
1646
  * Available frequencies for delivery reports and metrics updates
1234
1647
  */
@@ -1326,7 +1739,7 @@ export interface Product {
1326
1739
  */
1327
1740
  pricing_options: PricingOption[];
1328
1741
  forecast?: DeliveryForecast;
1329
- measurement?: Measurement;
1742
+ outcome_measurement?: OutcomeMeasurement;
1330
1743
  /**
1331
1744
  * Measurement provider and methodology for delivery metrics. The buyer accepts the declared provider as the source of truth for the buy. REQUIRED for all products.
1332
1745
  */
@@ -1369,7 +1782,11 @@ export interface Product {
1369
1782
  /**
1370
1783
  * Metric kinds this product can optimize for. Buyers should only request metric goals for kinds listed here.
1371
1784
  */
1372
- supported_metrics: ('clicks' | 'views' | 'completed_views' | 'viewed_seconds' | 'attention_seconds' | 'attention_score' | 'engagements' | 'follows' | 'saves' | 'profile_visits')[];
1785
+ supported_metrics: ('clicks' | 'views' | 'completed_views' | 'viewed_seconds' | 'attention_seconds' | 'attention_score' | 'engagements' | 'follows' | 'saves' | 'profile_visits' | 'reach')[];
1786
+ /**
1787
+ * Reach units this product can optimize for. Required when supported_metrics includes 'reach'. Buyers must set reach_unit to a value in this list on reach optimization goals — sellers reject unsupported values.
1788
+ */
1789
+ supported_reach_units?: ReachUnit[];
1373
1790
  /**
1374
1791
  * Video view duration thresholds (in seconds) this product supports for completed_views goals. Only relevant when supported_metrics includes 'completed_views'. When absent, the seller uses their platform default. Buyers must set view_duration_seconds to a value in this list — sellers reject unsupported values.
1375
1792
  */
@@ -1904,9 +2321,22 @@ export interface ForecastPoint {
1904
2321
  */
1905
2322
  budget: number;
1906
2323
  /**
1907
- * Forecasted metric values at this budget level. Keys are either forecastable-metric values for delivery/engagement (impressions, reach, spend, etc.) or event-type values for outcomes (purchase, lead, app_install, etc.). Values are ForecastRange objects (low/mid/high). Use { "mid": value } for point estimates. Include spend when the platform predicts it will differ from budget.
2324
+ * Forecasted metric values at this budget level. Keys are forecastable-metric enum values for delivery/engagement or event-type enum values for outcomes. Values are ForecastRange objects (low/mid/high). Use { "mid": value } for point estimates. Include spend when the platform predicts it will differ from budget. Additional keys beyond the documented properties are allowed for event-type values (purchase, lead, app_install, etc.).
1908
2325
  */
1909
2326
  metrics: {
2327
+ audience_size?: ForecastRange;
2328
+ reach?: ForecastRange;
2329
+ frequency?: ForecastRange;
2330
+ impressions?: ForecastRange;
2331
+ clicks?: ForecastRange;
2332
+ spend?: ForecastRange;
2333
+ views?: ForecastRange;
2334
+ completed_views?: ForecastRange;
2335
+ grps?: ForecastRange;
2336
+ engagements?: ForecastRange;
2337
+ follows?: ForecastRange;
2338
+ saves?: ForecastRange;
2339
+ profile_visits?: ForecastRange;
1910
2340
  [k: string]: ForecastRange | undefined;
1911
2341
  };
1912
2342
  }
@@ -1928,9 +2358,9 @@ export interface ForecastRange {
1928
2358
  high?: number;
1929
2359
  }
1930
2360
  /**
1931
- * Measurement capabilities included with a product
2361
+ * Business outcome measurement capabilities included with a product (e.g., incremental sales lift, brand lift, foot traffic). Distinct from delivery_measurement, which declares who counts ad impressions.
1932
2362
  */
1933
- export interface Measurement {
2363
+ export interface OutcomeMeasurement {
1934
2364
  /**
1935
2365
  * Type of measurement
1936
2366
  */
@@ -1940,9 +2370,9 @@ export interface Measurement {
1940
2370
  */
1941
2371
  attribution: string;
1942
2372
  /**
1943
- * Attribution window
2373
+ * Attribution window as a structured duration (e.g., {"interval": 30, "unit": "days"}).
1944
2374
  */
1945
- window?: string;
2375
+ window?: Duration;
1946
2376
  /**
1947
2377
  * Reporting frequency and format
1948
2378
  */
@@ -1976,11 +2406,57 @@ export interface ReportingCapabilities {
1976
2406
  * Whether this product supports creative-level metric breakdowns in delivery reporting (by_creative within by_package)
1977
2407
  */
1978
2408
  supports_creative_breakdown?: boolean;
2409
+ /**
2410
+ * Whether this product supports keyword-level metric breakdowns in delivery reporting (by_keyword within by_package)
2411
+ */
2412
+ supports_keyword_breakdown?: boolean;
2413
+ supports_geo_breakdown?: GeographicBreakdownSupport;
2414
+ /**
2415
+ * Whether this product supports device type breakdowns in delivery reporting (by_device_type within by_package)
2416
+ */
2417
+ supports_device_type_breakdown?: boolean;
2418
+ /**
2419
+ * Whether this product supports device platform breakdowns in delivery reporting (by_device_platform within by_package)
2420
+ */
2421
+ supports_device_platform_breakdown?: boolean;
2422
+ /**
2423
+ * Whether this product supports audience segment breakdowns in delivery reporting (by_audience within by_package)
2424
+ */
2425
+ supports_audience_breakdown?: boolean;
2426
+ /**
2427
+ * Whether this product supports placement breakdowns in delivery reporting (by_placement within by_package)
2428
+ */
2429
+ supports_placement_breakdown?: boolean;
1979
2430
  /**
1980
2431
  * Whether delivery data can be filtered to arbitrary date ranges. 'date_range' means the platform supports start_date/end_date parameters. 'lifetime_only' means the platform returns campaign lifetime totals and date range parameters are not accepted.
1981
2432
  */
1982
2433
  date_range_support: 'date_range' | 'lifetime_only';
1983
2434
  }
2435
+ /**
2436
+ * Geographic breakdown support for this product. Declares which geo levels and systems are available for by_geo reporting within by_package.
2437
+ */
2438
+ export interface GeographicBreakdownSupport {
2439
+ /**
2440
+ * Supports country-level geo breakdown (ISO 3166-1 alpha-2)
2441
+ */
2442
+ country?: boolean;
2443
+ /**
2444
+ * Supports region/state-level geo breakdown (ISO 3166-2)
2445
+ */
2446
+ region?: boolean;
2447
+ /**
2448
+ * Metro area breakdown support. Keys are metro-system enum values; true means supported.
2449
+ */
2450
+ metro?: {
2451
+ [k: string]: boolean | undefined;
2452
+ };
2453
+ /**
2454
+ * Postal area breakdown support. Keys are postal-system enum values; true means supported.
2455
+ */
2456
+ postal_area?: {
2457
+ [k: string]: boolean | undefined;
2458
+ };
2459
+ }
1984
2460
  /**
1985
2461
  * Creative requirements and restrictions for a product
1986
2462
  */
@@ -1991,6 +2467,10 @@ export interface CreativePolicy {
1991
2467
  * Whether creative templates are provided
1992
2468
  */
1993
2469
  templates_available: boolean;
2470
+ /**
2471
+ * Whether creatives must include provenance metadata. When true, the seller requires buyers to attach provenance declarations to creative submissions. The seller may independently verify claims via get_creative_features.
2472
+ */
2473
+ provenance_required?: boolean;
1994
2474
  }
1995
2475
  /**
1996
2476
  * Type of advertising property
@@ -2130,6 +2610,27 @@ export interface GetProductsResponse {
2130
2610
  * Whether the seller filtered results based on the provided catalog. True if the seller matched catalog items against its inventory. Absent or false if no catalog was provided or the seller does not support catalog matching.
2131
2611
  */
2132
2612
  catalog_applied?: boolean;
2613
+ /**
2614
+ * Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'.
2615
+ */
2616
+ refinement_applied?: {
2617
+ /**
2618
+ * Echoes the scope from the corresponding refine entry. Allows orchestrators to cross-validate alignment.
2619
+ */
2620
+ scope?: 'request' | 'product' | 'proposal';
2621
+ /**
2622
+ * Echoes the id from the corresponding refine entry (for product and proposal scopes).
2623
+ */
2624
+ id?: string;
2625
+ /**
2626
+ * 'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled — see notes for details. 'unable': the seller could not fulfill the ask — see notes for why.
2627
+ */
2628
+ status: 'applied' | 'partial' | 'unable';
2629
+ /**
2630
+ * Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'.
2631
+ */
2632
+ notes?: string;
2633
+ }[];
2133
2634
  pagination?: PaginationResponse;
2134
2635
  /**
2135
2636
  * When true, this response contains simulated data from sandbox mode.
@@ -2230,7 +2731,7 @@ export interface ProductAllocation {
2230
2731
  */
2231
2732
  export interface Error {
2232
2733
  /**
2233
- * Error code for programmatic handling
2734
+ * Error code for programmatic handling. Standard codes are defined in error-code.json and enable autonomous agent recovery. Sellers MAY use codes not in the standard vocabulary for platform-specific errors; agents MUST handle unknown codes gracefully by falling back to the recovery classification.
2234
2735
  */
2235
2736
  code: string;
2236
2737
  /**
@@ -2253,6 +2754,10 @@ export interface Error {
2253
2754
  * Additional task-specific error details
2254
2755
  */
2255
2756
  details?: {};
2757
+ /**
2758
+ * Agent recovery classification. transient: retry after delay (rate limit, service unavailable, timeout). correctable: fix the request and resend (invalid field, budget too low, creative rejected). terminal: requires human action (account suspended, payment required, account not found).
2759
+ */
2760
+ recovery?: 'transient' | 'correctable' | 'terminal';
2256
2761
  }
2257
2762
  /**
2258
2763
  * Standard cursor-based pagination metadata for list responses
@@ -2552,7 +3057,7 @@ export interface SyncCreativesSuccess {
2552
3057
  * This interface was referenced by `undefined`'s JSON-Schema definition
2553
3058
  * via the `patternProperty` "^[a-zA-Z0-9_-]+$".
2554
3059
  */
2555
- [k: string]: string;
3060
+ [k: string]: string | undefined;
2556
3061
  };
2557
3062
  }[];
2558
3063
  /**