@adcp/sdk 16.5.0 → 16.6.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 (236) hide show
  1. package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
  2. package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
  3. package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
  4. package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
  5. package/dist/lib/adapters/version/3.0/index.js +6 -0
  6. package/dist/lib/adapters/version/3.0/index.mjs +7 -1
  7. package/dist/lib/adapters/version/3.1/bidding.js +1 -1
  8. package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
  9. package/dist/lib/adapters/version/types.d.mts +5 -0
  10. package/dist/lib/adapters/version/types.d.ts +5 -0
  11. package/dist/lib/canonical-references/index.js +2 -0
  12. package/dist/lib/canonical-references/index.mjs +2 -0
  13. package/dist/lib/client/account-changes.d.mts +3 -1
  14. package/dist/lib/client/account-changes.d.ts +3 -1
  15. package/dist/lib/client/account-changes.js +22 -2
  16. package/dist/lib/client/account-changes.mjs +22 -2
  17. package/dist/lib/conformance/oracle.js +3 -2
  18. package/dist/lib/conformance/oracle.mjs +3 -2
  19. package/dist/lib/core/AgentClient.d.mts +165 -1
  20. package/dist/lib/core/AgentClient.d.ts +165 -1
  21. package/dist/lib/core/AgentClient.js +446 -8
  22. package/dist/lib/core/AgentClient.mjs +446 -8
  23. package/dist/lib/core/ConversationTypes.d.mts +8 -0
  24. package/dist/lib/core/ConversationTypes.d.ts +8 -0
  25. package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
  26. package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
  27. package/dist/lib/core/ProtocolResponseParser.js +28 -18
  28. package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
  29. package/dist/lib/core/ResponseValidator.js +1 -1
  30. package/dist/lib/core/ResponseValidator.mjs +1 -1
  31. package/dist/lib/core/SingleAgentClient.d.mts +116 -6
  32. package/dist/lib/core/SingleAgentClient.d.ts +116 -6
  33. package/dist/lib/core/SingleAgentClient.js +556 -84
  34. package/dist/lib/core/SingleAgentClient.mjs +545 -72
  35. package/dist/lib/core/TaskExecutor.d.mts +7 -0
  36. package/dist/lib/core/TaskExecutor.d.ts +7 -0
  37. package/dist/lib/core/TaskExecutor.js +23 -8
  38. package/dist/lib/core/TaskExecutor.mjs +23 -8
  39. package/dist/lib/core/task-status.d.mts +2 -0
  40. package/dist/lib/core/task-status.d.ts +2 -0
  41. package/dist/lib/core/task-status.js +11 -2
  42. package/dist/lib/core/task-status.mjs +9 -1
  43. package/dist/lib/errors/index.d.mts +22 -0
  44. package/dist/lib/errors/index.d.ts +22 -0
  45. package/dist/lib/errors/index.js +43 -0
  46. package/dist/lib/errors/index.mjs +42 -0
  47. package/dist/lib/identity-3.3/trust.d.mts +1 -4
  48. package/dist/lib/identity-3.3/trust.d.ts +1 -4
  49. package/dist/lib/identity-3.3/trust.js +34 -21
  50. package/dist/lib/identity-3.3/trust.mjs +34 -21
  51. package/dist/lib/identity-3.3/validation.js +5 -3
  52. package/dist/lib/identity-3.3/validation.mjs +6 -4
  53. package/dist/lib/index.d.mts +8 -54
  54. package/dist/lib/index.d.ts +8 -54
  55. package/dist/lib/index.js +15 -0
  56. package/dist/lib/index.mjs +11 -0
  57. package/dist/lib/media-buy/action-assessment.js +29 -3
  58. package/dist/lib/media-buy/action-assessment.mjs +32 -4
  59. package/dist/lib/media-buy/action-contracts.d.mts +3 -0
  60. package/dist/lib/media-buy/action-contracts.d.ts +3 -0
  61. package/dist/lib/media-buy/action-contracts.js +24 -1
  62. package/dist/lib/media-buy/action-contracts.mjs +22 -1
  63. package/dist/lib/media-buy/compatibility.js +6 -1
  64. package/dist/lib/media-buy/compatibility.mjs +6 -1
  65. package/dist/lib/media-buy/preflight.js +1 -1
  66. package/dist/lib/media-buy/preflight.mjs +3 -2
  67. package/dist/lib/media-buy/types.d.mts +6 -1
  68. package/dist/lib/media-buy/types.d.ts +6 -1
  69. package/dist/lib/protocols/mcp-modern.d.mts +2 -0
  70. package/dist/lib/protocols/mcp-modern.d.ts +2 -0
  71. package/dist/lib/protocols/mcp-modern.js +31 -5
  72. package/dist/lib/protocols/mcp-modern.mjs +31 -5
  73. package/dist/lib/protocols/mcp-scope.d.mts +6 -1
  74. package/dist/lib/protocols/mcp-scope.d.ts +6 -1
  75. package/dist/lib/protocols/mcp-scope.js +25 -3
  76. package/dist/lib/protocols/mcp-scope.mjs +24 -3
  77. package/dist/lib/protocols/mcp.js +12 -6
  78. package/dist/lib/protocols/mcp.mjs +13 -6
  79. package/dist/lib/reporting/inspection.js +1 -0
  80. package/dist/lib/reporting/inspection.mjs +1 -0
  81. package/dist/lib/schemas/browser.d.mts +2 -0
  82. package/dist/lib/schemas/browser.d.ts +2 -0
  83. package/dist/lib/schemas/browser.js +3 -0
  84. package/dist/lib/schemas/browser.mjs +2 -0
  85. package/dist/lib/schemas/index.d.mts +5 -2
  86. package/dist/lib/schemas/index.d.ts +5 -2
  87. package/dist/lib/schemas/index.js +5 -0
  88. package/dist/lib/schemas/index.mjs +4 -0
  89. package/dist/lib/server/account-response-identity.d.mts +17 -0
  90. package/dist/lib/server/account-response-identity.d.ts +17 -0
  91. package/dist/lib/server/account-response-identity.js +52 -0
  92. package/dist/lib/server/account-response-identity.mjs +28 -0
  93. package/dist/lib/server/account-sync-contract.js +1 -0
  94. package/dist/lib/server/account-sync-contract.mjs +1 -0
  95. package/dist/lib/server/create-adcp-server.js +32 -19
  96. package/dist/lib/server/create-adcp-server.mjs +36 -12
  97. package/dist/lib/server/decisioning/account.d.mts +13 -6
  98. package/dist/lib/server/decisioning/account.d.ts +13 -6
  99. package/dist/lib/server/decisioning/account.js +37 -15
  100. package/dist/lib/server/decisioning/account.mjs +37 -15
  101. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
  102. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
  103. package/dist/lib/server/decisioning/runtime/from-platform.js +6 -6
  104. package/dist/lib/server/decisioning/runtime/from-platform.mjs +6 -6
  105. package/dist/lib/server/index.d.mts +1 -1
  106. package/dist/lib/server/index.d.ts +1 -1
  107. package/dist/lib/server/index.js +2 -0
  108. package/dist/lib/server/index.mjs +2 -0
  109. package/dist/lib/server/media-buy-action-resolver.d.mts +3 -0
  110. package/dist/lib/server/media-buy-action-resolver.d.ts +3 -0
  111. package/dist/lib/server/media-buy-action-resolver.js +32 -0
  112. package/dist/lib/server/media-buy-action-resolver.mjs +32 -0
  113. package/dist/lib/server/media-buy-store.d.mts +26 -12
  114. package/dist/lib/server/media-buy-store.d.ts +26 -12
  115. package/dist/lib/server/media-buy-store.js +69 -21
  116. package/dist/lib/server/media-buy-store.mjs +69 -21
  117. package/dist/lib/server/responses.js +9 -1
  118. package/dist/lib/server/responses.mjs +9 -1
  119. package/dist/lib/server/state-machine.d.mts +10 -11
  120. package/dist/lib/server/state-machine.d.ts +10 -11
  121. package/dist/lib/server/state-machine.js +20 -5
  122. package/dist/lib/server/state-machine.mjs +19 -5
  123. package/dist/lib/signing/agent-fetch.d.mts +1 -1
  124. package/dist/lib/signing/agent-fetch.d.ts +1 -1
  125. package/dist/lib/signing/agent-fetch.js +3 -3
  126. package/dist/lib/signing/agent-fetch.mjs +3 -3
  127. package/dist/lib/testing/client.d.mts +1 -0
  128. package/dist/lib/testing/client.d.ts +1 -0
  129. package/dist/lib/testing/client.js +6 -5
  130. package/dist/lib/testing/client.mjs +6 -5
  131. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
  132. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
  133. package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
  134. package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
  135. package/dist/lib/testing/storyboard/compliance.js +62 -13
  136. package/dist/lib/testing/storyboard/compliance.mjs +63 -14
  137. package/dist/lib/testing/storyboard/context.d.mts +13 -3
  138. package/dist/lib/testing/storyboard/context.d.ts +13 -3
  139. package/dist/lib/testing/storyboard/context.js +15 -10
  140. package/dist/lib/testing/storyboard/context.mjs +15 -10
  141. package/dist/lib/testing/storyboard/default-invariants.js +10 -8
  142. package/dist/lib/testing/storyboard/default-invariants.mjs +11 -9
  143. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  144. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  145. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
  146. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
  147. package/dist/lib/testing/storyboard/runner.js +23 -10
  148. package/dist/lib/testing/storyboard/runner.mjs +23 -10
  149. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  150. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  151. package/dist/lib/testing/storyboard/validations.js +4 -1
  152. package/dist/lib/testing/storyboard/validations.mjs +4 -1
  153. package/dist/lib/testing/test-controller.js +3 -0
  154. package/dist/lib/testing/test-controller.mjs +3 -0
  155. package/dist/lib/types/asset-instances.d.mts +1 -1
  156. package/dist/lib/types/asset-instances.d.ts +1 -1
  157. package/dist/lib/types/index.d.mts +5 -0
  158. package/dist/lib/types/index.d.ts +5 -0
  159. package/dist/lib/types/index.js +6 -1
  160. package/dist/lib/types/index.mjs +4 -1
  161. package/dist/lib/types/inline-enums.generated.d.mts +30 -4
  162. package/dist/lib/types/inline-enums.generated.d.ts +30 -4
  163. package/dist/lib/types/inline-enums.generated.js +41 -2
  164. package/dist/lib/types/inline-enums.generated.mjs +28 -2
  165. package/dist/lib/types/media-buy-delivery-report.d.mts +4 -0
  166. package/dist/lib/types/media-buy-delivery-report.d.ts +4 -0
  167. package/dist/lib/types/media-buy-delivery-report.js +16 -0
  168. package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
  169. package/dist/lib/types/schemas.generated.d.ts +20 -69
  170. package/dist/lib/types/schemas.generated.js +29 -46
  171. package/dist/lib/types/schemas.generated.mjs +29 -46
  172. package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
  173. package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
  174. package/dist/lib/types/targeting-keys.generated.js +105 -0
  175. package/dist/lib/types/targeting-keys.generated.mjs +80 -0
  176. package/dist/lib/utils/adcp-version-config.js +5 -2
  177. package/dist/lib/utils/adcp-version-config.mjs +5 -2
  178. package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
  179. package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
  180. package/dist/lib/utils/envelope-status-compat.js +11 -5
  181. package/dist/lib/utils/envelope-status-compat.mjs +11 -5
  182. package/dist/lib/utils/response-unwrapper.js +18 -10
  183. package/dist/lib/utils/response-unwrapper.mjs +18 -10
  184. package/dist/lib/v2/format-schema/resolver.js +1 -1
  185. package/dist/lib/v2/format-schema/resolver.mjs +1 -1
  186. package/dist/lib/v2/projection/creative-delivery.js +123 -30
  187. package/dist/lib/v2/projection/creative-delivery.mjs +127 -30
  188. package/dist/lib/v2/projection/index.d.mts +1 -0
  189. package/dist/lib/v2/projection/index.d.ts +1 -0
  190. package/dist/lib/v2/projection/index.js +3 -0
  191. package/dist/lib/v2/projection/index.mjs +2 -0
  192. package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
  193. package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
  194. package/dist/lib/v2/projection/legacy-metadata.js +91 -0
  195. package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
  196. package/dist/lib/validation/compact-schema.d.mts +27 -0
  197. package/dist/lib/validation/compact-schema.d.ts +27 -0
  198. package/dist/lib/validation/compact-schema.js +276 -0
  199. package/dist/lib/validation/compact-schema.mjs +250 -0
  200. package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
  201. package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
  202. package/dist/lib/validation/media-buy-delivery-report.js +31 -0
  203. package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
  204. package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
  205. package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
  206. package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
  207. package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
  208. package/dist/lib/validation/schema-loader.js +86 -16
  209. package/dist/lib/validation/schema-loader.mjs +82 -16
  210. package/dist/lib/validation/schema-validator.d.mts +10 -19
  211. package/dist/lib/validation/schema-validator.d.ts +10 -19
  212. package/dist/lib/validation/schema-validator.js +136 -43
  213. package/dist/lib/validation/schema-validator.mjs +140 -44
  214. package/dist/lib/version.d.mts +3 -3
  215. package/dist/lib/version.d.ts +3 -3
  216. package/dist/lib/version.js +3 -3
  217. package/dist/lib/version.mjs +3 -3
  218. package/dist/lib/webhooks/index.d.mts +3 -0
  219. package/dist/lib/webhooks/index.d.ts +3 -0
  220. package/dist/lib/webhooks/index.js +3 -0
  221. package/dist/lib/webhooks/index.mjs +2 -0
  222. package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
  223. package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
  224. package/dist/lib/webhooks/media-buy-delivery.js +119 -0
  225. package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
  226. package/docs/TYPE-SUMMARY.md +2 -2
  227. package/docs/guides/BUILD-AN-AGENT.md +9 -1
  228. package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +135 -0
  229. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +15 -0
  230. package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
  231. package/docs/llms.txt +3 -3
  232. package/docs/migration-14.x-rc-worksheet.md +4 -4
  233. package/docs/migration-6.6-to-6.7.md +14 -0
  234. package/docs/migration-account-change-feed.md +19 -0
  235. package/docs/releases/sdk-16.6-adoption-fixes.md +33 -0
  236. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "16.5.0";
4
+ export declare const LIBRARY_VERSION = "16.6.0";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "16.5.0";
36
+ readonly library: "16.6.0";
37
37
  readonly adcp: "3.2.7";
38
38
  readonly compatibleVersions: readonly ["v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.1.25", "3.1.26", "3.1.27", "3.1.28", "3.1.29", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4", "3.2.5", "3.2.6", "3.2.7"];
39
- readonly generatedAt: "2026-10-25T14:43:55.588Z";
39
+ readonly generatedAt: "2026-10-27T06:39:57.335Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for
@@ -31,7 +31,7 @@ __export(version_exports, {
31
31
  toReleasePrecisionVersion: () => toReleasePrecisionVersion
32
32
  });
33
33
  module.exports = __toCommonJS(version_exports);
34
- const LIBRARY_VERSION = "16.5.0";
34
+ const LIBRARY_VERSION = "16.6.0";
35
35
  const ADCP_VERSION = "3.2.7";
36
36
  const ADCP_MAJOR_VERSION = 3;
37
37
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -104,10 +104,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
104
104
  "3.2.7"
105
105
  ];
106
106
  const VERSION_INFO = {
107
- library: "16.5.0",
107
+ library: "16.6.0",
108
108
  adcp: "3.2.7",
109
109
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
110
- generatedAt: "2026-10-25T14:43:55.588Z"
110
+ generatedAt: "2026-10-27T06:39:57.335Z"
111
111
  };
112
112
  function getAdcpVersion() {
113
113
  return ADCP_VERSION;
@@ -1,4 +1,4 @@
1
- const LIBRARY_VERSION = "16.5.0";
1
+ const LIBRARY_VERSION = "16.6.0";
2
2
  const ADCP_VERSION = "3.2.7";
3
3
  const ADCP_MAJOR_VERSION = 3;
4
4
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -71,10 +71,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
71
71
  "3.2.7"
72
72
  ];
73
73
  const VERSION_INFO = {
74
- library: "16.5.0",
74
+ library: "16.6.0",
75
75
  adcp: "3.2.7",
76
76
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
77
- generatedAt: "2026-10-25T14:43:55.588Z"
77
+ generatedAt: "2026-10-27T06:39:57.335Z"
78
78
  };
79
79
  function getAdcpVersion() {
80
80
  return ADCP_VERSION;
@@ -74,3 +74,6 @@ export type PreflightWebhookRequestResult = {
74
74
  };
75
75
  /** Validate headers and freshness before looking up a secret. Success does not authenticate the request. */
76
76
  export declare function preflightWebhookRequest(request: PreflightWebhookRequest, options?: PreflightWebhookRequestOptions): PreflightWebhookRequestResult;
77
+ export { parseMediaBuyDeliveryWebhook } from './media-buy-delivery.mjs';
78
+ export type { ParseMediaBuyDeliveryWebhookOptions, MediaBuyDeliveryWebhookEnvelope, MediaBuyDeliveryWebhookParseErrorCode, MediaBuyDeliveryWebhookParseResult, } from './media-buy-delivery.mjs';
79
+ export type { MediaBuyDeliveryReport } from '../types/media-buy-delivery-report.mjs';
@@ -74,3 +74,6 @@ export type PreflightWebhookRequestResult = {
74
74
  };
75
75
  /** Validate headers and freshness before looking up a secret. Success does not authenticate the request. */
76
76
  export declare function preflightWebhookRequest(request: PreflightWebhookRequest, options?: PreflightWebhookRequestOptions): PreflightWebhookRequestResult;
77
+ export { parseMediaBuyDeliveryWebhook } from './media-buy-delivery';
78
+ export type { ParseMediaBuyDeliveryWebhookOptions, MediaBuyDeliveryWebhookEnvelope, MediaBuyDeliveryWebhookParseErrorCode, MediaBuyDeliveryWebhookParseResult, } from './media-buy-delivery';
79
+ export type { MediaBuyDeliveryReport } from '../types/media-buy-delivery-report';
@@ -21,6 +21,7 @@ var webhooks_exports = {};
21
21
  __export(webhooks_exports, {
22
22
  WholesaleFeedWebhookNotificationError: () => import_webhook_notification.WholesaleFeedWebhookNotificationError,
23
23
  normalizeWholesaleFeedWebhookNotification: () => import_webhook_notification.normalizeWholesaleFeedWebhookNotification,
24
+ parseMediaBuyDeliveryWebhook: () => import_media_buy_delivery.parseMediaBuyDeliveryWebhook,
24
25
  parseWholesaleFeedWebhookNotification: () => import_webhook_notification.parseWholesaleFeedWebhookNotification,
25
26
  preflightWebhookRequest: () => preflightWebhookRequest,
26
27
  verifyWebhookRequest: () => verifyWebhookRequest
@@ -29,6 +30,7 @@ module.exports = __toCommonJS(webhooks_exports);
29
30
  var import_crypto = require("crypto");
30
31
  __reExport(webhooks_exports, require('../notifications/account-change-recorded.js'), module.exports);
31
32
  var import_webhook_notification = require('../wholesale-feed-sync/webhook-notification.js');
33
+ var import_media_buy_delivery = require('./media-buy-delivery.js');
32
34
  function verifyWebhookRequest(options) {
33
35
  const preflight = preflightWebhookRequest(options, {
34
36
  now: options.now,
@@ -172,6 +174,7 @@ function isHeaders(headers) {
172
174
  0 && (module.exports = {
173
175
  WholesaleFeedWebhookNotificationError,
174
176
  normalizeWholesaleFeedWebhookNotification,
177
+ parseMediaBuyDeliveryWebhook,
175
178
  parseWholesaleFeedWebhookNotification,
176
179
  preflightWebhookRequest,
177
180
  verifyWebhookRequest,
@@ -144,9 +144,11 @@ function normalizeHeaderValue(value) {
144
144
  function isHeaders(headers) {
145
145
  return typeof headers.get === "function";
146
146
  }
147
+ import { parseMediaBuyDeliveryWebhook } from "./media-buy-delivery.mjs";
147
148
  export {
148
149
  WholesaleFeedWebhookNotificationError,
149
150
  normalizeWholesaleFeedWebhookNotification,
151
+ parseMediaBuyDeliveryWebhook,
150
152
  parseWholesaleFeedWebhookNotification,
151
153
  preflightWebhookRequest,
152
154
  verifyWebhookRequest
@@ -0,0 +1,43 @@
1
+ import type { MCPWebhookPayload } from '../types/core.generated.mjs';
2
+ import type { MediaBuyDeliveryReport } from '../types/media-buy-delivery-report.mjs';
3
+ export interface ParseMediaBuyDeliveryWebhookOptions {
4
+ /** Trusted release negotiated with the seller. Defaults to the SDK pin; never read from the body. */
5
+ adcpVersion?: string;
6
+ /** Accept an unenveloped report and mark its wire format. Defaults to false. */
7
+ acceptBareDeliveryReport?: boolean;
8
+ }
9
+ /** AdCP 3.0 permits operation_id to be absent. No missing envelope fields are synthesized. */
10
+ export type MediaBuyDeliveryWebhookEnvelope = Omit<MCPWebhookPayload, 'result' | 'task_type' | 'operation_id'> & {
11
+ task_type: 'media_buy_delivery';
12
+ operation_id?: string;
13
+ result: MediaBuyDeliveryReport;
14
+ };
15
+ export type MediaBuyDeliveryWebhookParseErrorCode = 'webhook_envelope_invalid' | 'webhook_result_invalid' | 'webhook_unsupported_payload';
16
+ export type MediaBuyDeliveryWebhookParseResult = {
17
+ ok: true;
18
+ wireFormat: 'mcp_envelope';
19
+ adcpVersion: string;
20
+ envelope: MediaBuyDeliveryWebhookEnvelope;
21
+ result: MediaBuyDeliveryReport;
22
+ } | {
23
+ ok: true;
24
+ wireFormat: 'bare_delivery_report';
25
+ adcpVersion: string;
26
+ envelope?: undefined;
27
+ result: MediaBuyDeliveryReport;
28
+ } | {
29
+ ok: false;
30
+ code: MediaBuyDeliveryWebhookParseErrorCode;
31
+ message: string;
32
+ errors: readonly string[];
33
+ };
34
+ /**
35
+ * Validate an ALREADY AUTHENTICATED delivery webhook. This performs no signature,
36
+ * sender, registration, or replay verification. Verify the original request bytes
37
+ * first and select adcpVersion from trusted seller/buy state. Malformed bodies
38
+ * return diagnostics; invalid version configuration throws ConfigurationError.
39
+ *
40
+ * Envelope status follows the selected release's task-status enum. A delayed
41
+ * notification may use working; notification_type is independent of task status.
42
+ */
43
+ export declare function parseMediaBuyDeliveryWebhook(body: unknown, options?: ParseMediaBuyDeliveryWebhookOptions): MediaBuyDeliveryWebhookParseResult;
@@ -0,0 +1,43 @@
1
+ import type { MCPWebhookPayload } from '../types/core.generated';
2
+ import type { MediaBuyDeliveryReport } from '../types/media-buy-delivery-report';
3
+ export interface ParseMediaBuyDeliveryWebhookOptions {
4
+ /** Trusted release negotiated with the seller. Defaults to the SDK pin; never read from the body. */
5
+ adcpVersion?: string;
6
+ /** Accept an unenveloped report and mark its wire format. Defaults to false. */
7
+ acceptBareDeliveryReport?: boolean;
8
+ }
9
+ /** AdCP 3.0 permits operation_id to be absent. No missing envelope fields are synthesized. */
10
+ export type MediaBuyDeliveryWebhookEnvelope = Omit<MCPWebhookPayload, 'result' | 'task_type' | 'operation_id'> & {
11
+ task_type: 'media_buy_delivery';
12
+ operation_id?: string;
13
+ result: MediaBuyDeliveryReport;
14
+ };
15
+ export type MediaBuyDeliveryWebhookParseErrorCode = 'webhook_envelope_invalid' | 'webhook_result_invalid' | 'webhook_unsupported_payload';
16
+ export type MediaBuyDeliveryWebhookParseResult = {
17
+ ok: true;
18
+ wireFormat: 'mcp_envelope';
19
+ adcpVersion: string;
20
+ envelope: MediaBuyDeliveryWebhookEnvelope;
21
+ result: MediaBuyDeliveryReport;
22
+ } | {
23
+ ok: true;
24
+ wireFormat: 'bare_delivery_report';
25
+ adcpVersion: string;
26
+ envelope?: undefined;
27
+ result: MediaBuyDeliveryReport;
28
+ } | {
29
+ ok: false;
30
+ code: MediaBuyDeliveryWebhookParseErrorCode;
31
+ message: string;
32
+ errors: readonly string[];
33
+ };
34
+ /**
35
+ * Validate an ALREADY AUTHENTICATED delivery webhook. This performs no signature,
36
+ * sender, registration, or replay verification. Verify the original request bytes
37
+ * first and select adcpVersion from trusted seller/buy state. Malformed bodies
38
+ * return diagnostics; invalid version configuration throws ConfigurationError.
39
+ *
40
+ * Envelope status follows the selected release's task-status enum. A delayed
41
+ * notification may use working; notification_type is independent of task status.
42
+ */
43
+ export declare function parseMediaBuyDeliveryWebhook(body: unknown, options?: ParseMediaBuyDeliveryWebhookOptions): MediaBuyDeliveryWebhookParseResult;
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var media_buy_delivery_exports = {};
20
+ __export(media_buy_delivery_exports, {
21
+ parseMediaBuyDeliveryWebhook: () => parseMediaBuyDeliveryWebhook,
22
+ prepareMediaBuyDeliveryWebhookValidation: () => prepareMediaBuyDeliveryWebhookValidation
23
+ });
24
+ module.exports = __toCommonJS(media_buy_delivery_exports);
25
+ var import_node_util = require("node:util");
26
+ var import_account_change_json = require('../client/account-change-json.js');
27
+ var import_errors = require('../errors/index.js');
28
+ var import_adcp_version_config = require('../utils/adcp-version-config.js');
29
+ var import_schema_loader = require('../validation/schema-loader.js');
30
+ const MAX_BODY_BYTES = 16 * 1024 * 1024;
31
+ const ENVELOPE_FIELDS = ["result", "task_type", "task_id", "operation_id", "idempotency_key", "timestamp"];
32
+ function prepareMediaBuyDeliveryWebhookValidation(version) {
33
+ const adcpVersion = (0, import_adcp_version_config.resolveAdcpVersion)(version);
34
+ const validateEnvelope = (0, import_schema_loader.getMediaBuyDeliveryEnvelopeValidator)(adcpVersion);
35
+ const validateResult = (0, import_schema_loader.getSchemaValidatorByRef)(
36
+ (0, import_adcp_version_config.isPre31AdcpVersion)(adcpVersion) ? "media-buy/get-media-buy-delivery-response.json" : "media-buy/media-buy-delivery-webhook-result.json",
37
+ adcpVersion
38
+ );
39
+ if (!validateEnvelope || !validateResult) {
40
+ throw new import_errors.ConfigurationError("Bundled delivery webhook schemas are unavailable.", "adcpVersion");
41
+ }
42
+ return { adcpVersion, validateEnvelope, validateResult };
43
+ }
44
+ function parseMediaBuyDeliveryWebhook(body, options = {}) {
45
+ const { adcpVersion, validateEnvelope, validateResult } = prepareMediaBuyDeliveryWebhookValidation(
46
+ options.adcpVersion
47
+ );
48
+ let parsed;
49
+ try {
50
+ if (typeof body === "string" || body instanceof Uint8Array) {
51
+ if ((typeof body === "string" ? Buffer.byteLength(body) : body.byteLength) > MAX_BODY_BYTES) {
52
+ throw new Error("Body is too large");
53
+ }
54
+ parsed = JSON.parse(
55
+ typeof body === "string" ? body : new import_node_util.TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(body)
56
+ );
57
+ } else {
58
+ parsed = body;
59
+ }
60
+ (0, import_account_change_json.assertAccountChangeJsonSize)(parsed, MAX_BODY_BYTES);
61
+ parsed = structuredClone(parsed);
62
+ } catch {
63
+ return failure("webhook_envelope_invalid", [
64
+ "Webhook body must be valid JSON within 16 MiB and 64 nesting levels."
65
+ ]);
66
+ }
67
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
68
+ return failure("webhook_envelope_invalid", ["Webhook body must be an object."]);
69
+ }
70
+ const envelope = parsed;
71
+ const bare = Object.hasOwn(envelope, "media_buy_deliveries") && !ENVELOPE_FIELDS.some((field) => Object.hasOwn(envelope, field));
72
+ if (bare && options.acceptBareDeliveryReport !== true) {
73
+ return failure("webhook_unsupported_payload", [
74
+ "Bare delivery reports require acceptBareDeliveryReport: true; the default expects an MCP envelope with result."
75
+ ]);
76
+ }
77
+ if (!bare) {
78
+ if (typeof envelope.task_type === "string" && envelope.task_type !== "media_buy_delivery") {
79
+ return failure("webhook_unsupported_payload", ["task_type must be media_buy_delivery."]);
80
+ }
81
+ if (!validateEnvelope(envelope)) return failure("webhook_envelope_invalid", diagnostics(validateEnvelope.errors));
82
+ }
83
+ const result = bare ? envelope : envelope.result;
84
+ if (!validateResult(result))
85
+ return failure("webhook_result_invalid", diagnostics(validateResult.errors, bare ? "" : "result"));
86
+ if (bare)
87
+ return { ok: true, wireFormat: "bare_delivery_report", adcpVersion, result };
88
+ return {
89
+ ok: true,
90
+ wireFormat: "mcp_envelope",
91
+ adcpVersion,
92
+ envelope,
93
+ result
94
+ };
95
+ }
96
+ function failure(code, errors) {
97
+ return { ok: false, code, message: errors.join("; "), errors };
98
+ }
99
+ function diagnostics(errors, prefix = "") {
100
+ if (!errors?.length) return [`${prefix || "body"} is invalid`];
101
+ return errors.slice(0, 20).map((error) => {
102
+ const fields = error.instancePath.split("/").slice(1).map((field) => field.replace(/~1/g, "/").replace(/~0/g, "~"));
103
+ if (error.keyword === "required" && typeof error.params.missingProperty === "string")
104
+ fields.push(error.params.missingProperty);
105
+ if (error.keyword === "additionalProperties" && typeof error.params.additionalProperty === "string")
106
+ fields.push(error.params.additionalProperty);
107
+ let path = prefix;
108
+ for (const field of fields) {
109
+ const bounded = field.length > 80 ? field.slice(0, 80) + "\u2026" : field;
110
+ path += /^(0|[1-9][0-9]*)$/.test(bounded) ? `[${bounded}]` : /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(bounded) ? `${path ? "." : ""}${bounded}` : `[${JSON.stringify(bounded)}]`;
111
+ }
112
+ return `${path || "body"} ${error.keyword === "required" ? "is required" : error.message ?? "is invalid"}`;
113
+ });
114
+ }
115
+ // Annotate the CommonJS export names for ESM import in node:
116
+ 0 && (module.exports = {
117
+ parseMediaBuyDeliveryWebhook,
118
+ prepareMediaBuyDeliveryWebhookValidation
119
+ });
@@ -0,0 +1,94 @@
1
+ import { TextDecoder } from "node:util";
2
+ import { assertAccountChangeJsonSize } from "../client/account-change-json.mjs";
3
+ import { ConfigurationError } from "../errors/index.mjs";
4
+ import { isPre31AdcpVersion, resolveAdcpVersion } from "../utils/adcp-version-config.mjs";
5
+ import { getMediaBuyDeliveryEnvelopeValidator, getSchemaValidatorByRef } from "../validation/schema-loader.mjs";
6
+ const MAX_BODY_BYTES = 16 * 1024 * 1024;
7
+ const ENVELOPE_FIELDS = ["result", "task_type", "task_id", "operation_id", "idempotency_key", "timestamp"];
8
+ function prepareMediaBuyDeliveryWebhookValidation(version) {
9
+ const adcpVersion = resolveAdcpVersion(version);
10
+ const validateEnvelope = getMediaBuyDeliveryEnvelopeValidator(adcpVersion);
11
+ const validateResult = getSchemaValidatorByRef(
12
+ isPre31AdcpVersion(adcpVersion) ? "media-buy/get-media-buy-delivery-response.json" : "media-buy/media-buy-delivery-webhook-result.json",
13
+ adcpVersion
14
+ );
15
+ if (!validateEnvelope || !validateResult) {
16
+ throw new ConfigurationError("Bundled delivery webhook schemas are unavailable.", "adcpVersion");
17
+ }
18
+ return { adcpVersion, validateEnvelope, validateResult };
19
+ }
20
+ function parseMediaBuyDeliveryWebhook(body, options = {}) {
21
+ const { adcpVersion, validateEnvelope, validateResult } = prepareMediaBuyDeliveryWebhookValidation(
22
+ options.adcpVersion
23
+ );
24
+ let parsed;
25
+ try {
26
+ if (typeof body === "string" || body instanceof Uint8Array) {
27
+ if ((typeof body === "string" ? Buffer.byteLength(body) : body.byteLength) > MAX_BODY_BYTES) {
28
+ throw new Error("Body is too large");
29
+ }
30
+ parsed = JSON.parse(
31
+ typeof body === "string" ? body : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(body)
32
+ );
33
+ } else {
34
+ parsed = body;
35
+ }
36
+ assertAccountChangeJsonSize(parsed, MAX_BODY_BYTES);
37
+ parsed = structuredClone(parsed);
38
+ } catch {
39
+ return failure("webhook_envelope_invalid", [
40
+ "Webhook body must be valid JSON within 16 MiB and 64 nesting levels."
41
+ ]);
42
+ }
43
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
44
+ return failure("webhook_envelope_invalid", ["Webhook body must be an object."]);
45
+ }
46
+ const envelope = parsed;
47
+ const bare = Object.hasOwn(envelope, "media_buy_deliveries") && !ENVELOPE_FIELDS.some((field) => Object.hasOwn(envelope, field));
48
+ if (bare && options.acceptBareDeliveryReport !== true) {
49
+ return failure("webhook_unsupported_payload", [
50
+ "Bare delivery reports require acceptBareDeliveryReport: true; the default expects an MCP envelope with result."
51
+ ]);
52
+ }
53
+ if (!bare) {
54
+ if (typeof envelope.task_type === "string" && envelope.task_type !== "media_buy_delivery") {
55
+ return failure("webhook_unsupported_payload", ["task_type must be media_buy_delivery."]);
56
+ }
57
+ if (!validateEnvelope(envelope)) return failure("webhook_envelope_invalid", diagnostics(validateEnvelope.errors));
58
+ }
59
+ const result = bare ? envelope : envelope.result;
60
+ if (!validateResult(result))
61
+ return failure("webhook_result_invalid", diagnostics(validateResult.errors, bare ? "" : "result"));
62
+ if (bare)
63
+ return { ok: true, wireFormat: "bare_delivery_report", adcpVersion, result };
64
+ return {
65
+ ok: true,
66
+ wireFormat: "mcp_envelope",
67
+ adcpVersion,
68
+ envelope,
69
+ result
70
+ };
71
+ }
72
+ function failure(code, errors) {
73
+ return { ok: false, code, message: errors.join("; "), errors };
74
+ }
75
+ function diagnostics(errors, prefix = "") {
76
+ if (!errors?.length) return [`${prefix || "body"} is invalid`];
77
+ return errors.slice(0, 20).map((error) => {
78
+ const fields = error.instancePath.split("/").slice(1).map((field) => field.replace(/~1/g, "/").replace(/~0/g, "~"));
79
+ if (error.keyword === "required" && typeof error.params.missingProperty === "string")
80
+ fields.push(error.params.missingProperty);
81
+ if (error.keyword === "additionalProperties" && typeof error.params.additionalProperty === "string")
82
+ fields.push(error.params.additionalProperty);
83
+ let path = prefix;
84
+ for (const field of fields) {
85
+ const bounded = field.length > 80 ? field.slice(0, 80) + "\u2026" : field;
86
+ path += /^(0|[1-9][0-9]*)$/.test(bounded) ? `[${bounded}]` : /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(bounded) ? `${path ? "." : ""}${bounded}` : `[${JSON.stringify(bounded)}]`;
87
+ }
88
+ return `${path || "body"} ${error.keyword === "required" ? "is required" : error.message ?? "is invalid"}`;
89
+ });
90
+ }
91
+ export {
92
+ parseMediaBuyDeliveryWebhook,
93
+ prepareMediaBuyDeliveryWebhookValidation
94
+ };
@@ -1,7 +1,7 @@
1
1
  # AdCP Type Summary
2
2
 
3
- > Generated at: 2026-10-25
4
- > @adcp/sdk v16.5.0
3
+ > Generated at: 2026-10-27
4
+ > @adcp/sdk v16.6.0
5
5
 
6
6
  Curated reference of the types that matter for using the AdCP client. For full generated types see `src/lib/types/tools.generated.ts` and `src/lib/types/core.generated.ts`.
7
7
 
@@ -252,11 +252,19 @@ Six helper families adopters reach for. Pick what your agent shape needs:
252
252
  | `InMemoryImplicitAccountStore` (Shape A) / `createOAuthPassthroughResolver` (Shape B) / `createRosterAccountStore` (Shape C) | Reference `AccountStore` shapes. Shape A: `'implicit'` buyer-driven onboarding. Shape B: vendor OAuth + `/me/adaccounts`. Shape C: publisher-curated roster. |
253
253
  | `createTenantRegistry` (host-routed) / `createTenantStore` (account-routed) | Multi-tenant. Host-routed = one server per tenant + tenant-id keyed lookup. Account-routed = one server with built-in fail-closed tenant-isolation gate on `upsert` / `syncGovernance`. |
254
254
  | `BuyerAgentRegistry.signingOnly` / `bearerOnly` / `mixed` (+ `cached`) | Durable buyer-agent identity. Resolved `BuyerAgent` flows through `ctx.agent` to every `AccountStore` method and `tasks_get` polling. `BuyerAgent.status === 'suspended' \| 'blocked'` triggers `AGENT_SUSPENDED` / `AGENT_BLOCKED`; `sync_accounts.billing` is enforced against `BuyerAgent.billing_capabilities`. See [`docs/migration-buyer-agent-registry.md`](../migration-buyer-agent-registry.md). |
255
- | `MEDIA_BUY_TRANSITIONS` / `assertMediaBuyTransition` (+ creative pair) | Canonical lifecycle graph the storyboard runner uses. `assertMediaBuyTransition(from, to)` throws `AdcpError` with the spec-correct code (`NOT_CANCELLABLE` / `INVALID_STATE`). Replaces local copies of the status graph. |
255
+ | `MEDIA_BUY_TRANSITIONS` / `getMediaBuyTransitions` / `assertMediaBuyTransition` (+ creative pair) | Canonical lifecycle graphs shared with the storyboard runner. `getMediaBuyTransitions(adcpVersion)` selects the served release; `MEDIA_BUY_TRANSITIONS` uses the SDK default. `assertMediaBuyTransition(from, to, adcpVersion?)` throws `AdcpError` with the spec-correct code (`NOT_CANCELLABLE` / `INVALID_STATE`). Replaces local copies of the status graph. |
256
256
  | `createMediaBuyStore({ store })` | Opt-in `targeting_overlay` echo on `get_media_buys`. Sellers claiming `property-lists` / `collection-lists` MUST echo the persisted list reference. |
257
257
 
258
258
  The full migration recipe walking adopters through each is at [`docs/migration-6.6-to-6.7.md`](../migration-6.6-to-6.7.md). The `examples/hello_*` family demonstrates each helper in a runnable adapter.
259
259
 
260
+ When serving AdCP 3.3 or its beta/RC candidates, pass the negotiated release to
261
+ `isLegalMediaBuyTransition` or `assertMediaBuyTransition` as the optional third
262
+ argument. A blocking creative review rejection can move a not-yet-active buy
263
+ from `pending_start` to `pending_creatives`; active and paused buys still cannot
264
+ rewind to a pending state. Omitting the version keeps the SDK default release's
265
+ contract. The storyboard runner selects the graph from the seller's response
266
+ version, falling back to the run's `adcpVersion` and then the SDK default.
267
+
260
268
  ### Exposing your agent over A2A (preview)
261
269
 
262
270
  MCP is the default transport. To additionally expose the same `AdcpServer` over A2A JSON-RPC — so A2A-native buyers can discover and call your agent — mount `createA2AAdapter`:
@@ -0,0 +1,135 @@
1
+ # Parsing media-buy delivery webhooks
2
+
3
+ Use `parseMediaBuyDeliveryWebhook` from `@adcp/sdk/webhooks` after your receiver
4
+ has authenticated the original HTTP body and enforced replay protection. It
5
+ validates delivery content without requiring an `AgentClient`, an SDK callback
6
+ registry, or a signature-verification strategy. It performs no authentication
7
+ itself; `ok: true` means the payload is valid, not that its sender is trusted.
8
+
9
+ ```typescript
10
+ import { parseMediaBuyDeliveryWebhook } from '@adcp/sdk/webhooks';
11
+
12
+ // Call only after signature verification. Load the version from the registered
13
+ // seller/buy record, rather than trusting a version claim in the request body.
14
+ function parseAuthenticatedDelivery(verifiedRawBody: Uint8Array, negotiatedVersion: string) {
15
+ const parsed = parseMediaBuyDeliveryWebhook(verifiedRawBody, {
16
+ adcpVersion: negotiatedVersion,
17
+ });
18
+ if (!parsed.ok) {
19
+ // Suitable for a 400 response: paths are readable and omit report values (map key names can appear in paths).
20
+ // e.g. result.media_buy_deliveries[0].by_package is required
21
+ return { status: 400, error: parsed.message, errors: parsed.errors };
22
+ }
23
+ return { status: 200, report: parsed.result };
24
+ }
25
+ ```
26
+
27
+ Pass the exact bytes you authenticated to avoid parsing a different body from
28
+ JSON middleware. The parser also accepts a parsed JSON object or a JSON string. It returns
29
+ a detached copy of validated data and preserves the seller's fields. It does
30
+ not add a task status, operation ID, currency, package breakdown, or other
31
+ missing data. Bodies are limited to 16 MiB and 64 nesting levels before schema
32
+ validation. Schema diagnostics use fail-fast validation and readable paths.
33
+ Invalid bodies return one of:
34
+
35
+ | Code | Meaning |
36
+ | --- | --- |
37
+ | `webhook_envelope_invalid` | Malformed JSON, invalid envelope metadata, or a missing result. |
38
+ | `webhook_result_invalid` | The nested delivery report fails the selected release's schema. |
39
+ | `webhook_unsupported_payload` | Another task type, or an unenveloped report without explicit opt-in. |
40
+
41
+ An invalid or unbundled `adcpVersion` is a caller configuration error and throws
42
+ `ConfigurationError`. Omission selects the SDK's protocol pin. The body does not
43
+ select its own validation release.
44
+
45
+ ## Select the release used for the buy
46
+
47
+ A reporting webhook does not provide a trustworthy negotiated-version field.
48
+ Keep that release with the callback/buy registration and supply it for every
49
+ report. Stable patch pins select their bundled minor contract; preview pins
50
+ remain exact.
51
+
52
+ | Release | Report validation | Envelope details |
53
+ | --- | --- | --- |
54
+ | 3.0 | `get-media-buy-delivery-response.json`; report-wide currency is required. | `operation_id` is optional and remains absent when omitted. The parser accepts the documented `media_buy_delivery` discriminator even though the old task enum omits it. |
55
+ | 3.1 | `media-buy-delivery-webhook-result.json`; report-wide currency is required. | `operation_id` is required. |
56
+ | 3.2 | Dedicated webhook-result schema; report-wide currency is optional. | `operation_id` is required. |
57
+
58
+ All releases require `by_package` on each delivery row. The SDK's schema loader
59
+ handles both relative and absolute schema IDs. No external `$ref` traversal or
60
+ network fetch is needed.
61
+
62
+ On SDK 16, the standalone parser is additive. Existing `verifyAndParseWebhook`
63
+ contracts remain unchanged; receivers needing per-buy release selection can pass
64
+ already-authenticated bytes to this parser.
65
+
66
+ ## Bare-report compatibility is explicit
67
+
68
+ The default rejects a body with top-level `media_buy_deliveries` and no MCP
69
+ envelope. For a temporary migration, opt in explicitly:
70
+
71
+ ```typescript
72
+ const parsed = parseMediaBuyDeliveryWebhook(verifiedRawBody, {
73
+ adcpVersion: savedBuy.adcpVersion,
74
+ acceptBareDeliveryReport: true,
75
+ });
76
+ if (parsed.ok && parsed.wireFormat === 'bare_delivery_report') {
77
+ // Record the seller's protocol violation and repair its callback format.
78
+ // parsed.envelope is undefined; no transport identity has been invented.
79
+ }
80
+ ```
81
+
82
+ The report still undergoes release-specific validation. A poll-shaped report
83
+ with only a task `status` and no envelope identity is also bare; any such field
84
+ is preserved when the selected report schema permits it. An incomplete or invalid
85
+ envelope never falls back to bare-report acceptance. A normal envelope returns
86
+ `wireFormat: 'mcp_envelope'` and the validated `envelope`. Authentication and
87
+ sender, account, media-buy authorization, and deduplication remain the receiver's
88
+ responsibility in either format.
89
+
90
+ ## A shared delivery body for polling and pushing
91
+
92
+ `MediaBuyDeliveryReport` imports from `@adcp/sdk/types` or `@adcp/sdk/webhooks`.
93
+ `MediaBuyDeliveryReportSchema` imports from `@adcp/sdk/schemas` and
94
+ `@adcp/sdk/schemas/browser`. This payload-only shape accepts a polled report or a
95
+ webhook result without requiring a task-level `status`. The shared TypeScript type and these Zod schemas describe
96
+ the SDK's current pin; use the parser above for older release-specific checks.
97
+
98
+ `GetMediaBuyDeliveryResponseSchema` still requires task status through its
99
+ referenced `core/protocol-envelope.json`. The absence of `status` from the
100
+ response document's own `required` list does not remove that inherited
101
+ requirement. Use the shared body schema for ingestion, and the full response
102
+ schema for a poll's protocol envelope. `MediaBuyDeliveryWebhookResultSchema`
103
+ now retains the canonical required row fields, including `by_package`.
104
+
105
+ ## Envelope status and notification type are independent
106
+
107
+ The parser accepts the selected release's task-status enum; it does not require
108
+ `completed` for all reporting messages. For example, `notification_type:
109
+ 'delayed'` may accompany `status: 'working'` when a valid report is present.
110
+ `delayed` itself is not a task status. A progress-only message without a report
111
+ is not a delivery-data webhook.
112
+
113
+ `notification_type: 'final'` concerns report scheduling; envelope `completed`
114
+ does not mean the media buy has finished. Per-buy state remains in
115
+ `media_buy_deliveries[].status`. This follows the protocol's
116
+ [envelope/result distinction](https://github.com/adcontextprotocol/adcp/blob/v3.3.0-beta.0/docs/building/by-layer/L3/webhooks.mdx#payload-anatomy-envelope-vs-result).
117
+
118
+ The protocol also requires receivers to ignore `aggregated_totals` in pushed
119
+ reports as an authority source. The parser preserves that field for auditing
120
+ when supplied; reconcile authoritative totals through a poll or per-delivery
121
+ rows instead.
122
+
123
+ For offline tooling that needs all raw JSON Schema diagnostics,
124
+ `@adcp/sdk/schemas` also exports `getSchemaValidatorByRef`. Its default is
125
+ fail-fast; complete diagnostics are an explicit option:
126
+
127
+ ```typescript
128
+ import { getSchemaValidatorByRef } from '@adcp/sdk/schemas';
129
+ const validate = getSchemaValidatorByRef(
130
+ 'media-buy/media-buy-delivery-webhook-result.json',
131
+ '3.1',
132
+ undefined,
133
+ { allErrors: true },
134
+ );
135
+ ```
@@ -162,6 +162,21 @@ Await every operation before the scope callback returns; the callback owns the s
162
162
 
163
163
  Inside a scope the endpoint probe, capability discovery, `tools/list` and tool calls share one negotiated session per identity. `closeScopedConnections()` closes the current MCP scope's sessions early and does nothing when no MCP scope is active (A2A connections are not scoped). Nested `withMCPConnectionScope` calls join the outer scope unless you pass `{ isolate: true }`.
164
164
 
165
+ An implicit high-level task scope closes local transports without sending session
166
+ `DELETE` when its final result is accepted `submitted`, `working`, `input-required`,
167
+ `auth-required`, or `deferred` work. (`deferred` is a task/HITL result, not an MCP
168
+ wire status.) The owning task's final result decides; an earlier nested result
169
+ cannot change a completed owner's cleanup. Completed tasks keep normal session
170
+ termination.
171
+
172
+ An explicit `withMCPConnectionScope` workflow remains caller-owned: its final
173
+ cleanup terminates its sessions even if a call inside returned `submitted` or
174
+ `working`. End that callback only when you intend to relinquish those sessions.
175
+ Implicit preservation means avoiding termination, not retaining a connection for
176
+ resumption: local clients are closed and evicted, later calls open fresh sessions,
177
+ and the seller owns expiration of its retained sessions. A preserved implicit
178
+ scope can include discovery sessions as well as the dispatch session.
179
+
165
180
  ### One exception: the first legacy handoff
166
181
 
167
182
  For a seller on the pre-2026 MCP protocol era, the SDK negotiates with the v2 client first and then hands the call to the v1 client so 2025 Tasks keep working. That handoff is a cold cost the SDK cannot avoid: the first scope against such a seller opens one classification handshake plus one shared v1 session. Within the scope everything after that (probe aside) shares the v1 session, including `tools/list`, and the classification is remembered across scopes for five minutes, so a later scope opens only its own session. Modern-era sellers need a single negotiation per scope.