Proposal
Reserve ctx_metadata as a top-level optional key on the following AdCP resource objects, with semantics: publisher-to-SDK round-trip cache for adapter-internal state. MUST be stripped before wire egress. MUST NOT be relied on by buyers.
Resources that get the reserved key:
Product
MediaBuy
Package
Creative
AudienceSegment
Signal
RightsGrant
PropertyList
CollectionList
Why this needs spec coordination
This is a non-binding convention, not a wire-protocol field. AdCP buyers never see ctx_metadata — SDKs strip it from outgoing payloads. But two SDKs converging on the same field name by accident is interop debt: a third SDK (Go, Rust, the next salesagent rewrite) will pick a different name and break the pattern. One paragraph in the spec turns it into a convention that survives ecosystem expansion.
Prior art — Prebid salesagent
The reference prebid/salesagent Python implementation uses an implementation_config JSON column on the Product model for the same purpose (GAM ad_unit_ids per product, key_value_pairs, placement_ids, etc.). Keyword-name implementation_config is salesagent-specific; the convention is the round-trip pattern itself.
Wire-compat check
All 9 resource schemas above already declare additionalProperties: true in AdCP 3.0.0. Adopting ctx_metadata as a recognized top-level key is forward-compatible at the wire level — no schema changes needed, just spec note acknowledging the reserved name.
ctx_metadata does not collide with any existing AdCP 3.0 wire field across core/, signals/, creative/, media-buy/, property/, governance/, brand/ schemas. Distinct from:
ext — vendor-namespaced, buyer-visible (different semantics)
context — caller-echoed (different semantics)
Implementation
@adcp/sdk 6.1 ships the TypeScript-side CtxMetadataStore (in-memory + Postgres backends) with the field name ctx_metadata. The Python SDK (adcp-client-python PR #316) is in design phase and will adopt the same name; spec note locks the convention before two SDKs ship with divergent names.
Ask
Add a one-paragraph spec note (probably in core/conventions.md or equivalent) reserving the key and documenting the round-trip semantics. Not changing wire payloads, not changing schemas. Just naming.
Proposal
Reserve
ctx_metadataas a top-level optional key on the following AdCP resource objects, with semantics: publisher-to-SDK round-trip cache for adapter-internal state. MUST be stripped before wire egress. MUST NOT be relied on by buyers.Resources that get the reserved key:
ProductMediaBuyPackageCreativeAudienceSegmentSignalRightsGrantPropertyListCollectionListWhy this needs spec coordination
This is a non-binding convention, not a wire-protocol field. AdCP buyers never see
ctx_metadata— SDKs strip it from outgoing payloads. But two SDKs converging on the same field name by accident is interop debt: a third SDK (Go, Rust, the next salesagent rewrite) will pick a different name and break the pattern. One paragraph in the spec turns it into a convention that survives ecosystem expansion.Prior art — Prebid
salesagentThe reference
prebid/salesagentPython implementation uses animplementation_configJSON column on the Product model for the same purpose (GAMad_unit_idsper product,key_value_pairs,placement_ids, etc.). Keyword-nameimplementation_configis salesagent-specific; the convention is the round-trip pattern itself.Wire-compat check
All 9 resource schemas above already declare
additionalProperties: truein AdCP 3.0.0. Adoptingctx_metadataas a recognized top-level key is forward-compatible at the wire level — no schema changes needed, just spec note acknowledging the reserved name.ctx_metadatadoes not collide with any existing AdCP 3.0 wire field acrosscore/,signals/,creative/,media-buy/,property/,governance/,brand/schemas. Distinct from:ext— vendor-namespaced, buyer-visible (different semantics)context— caller-echoed (different semantics)Implementation
@adcp/sdk 6.1 ships the TypeScript-side
CtxMetadataStore(in-memory + Postgres backends) with the field namectx_metadata. The Python SDK (adcp-client-pythonPR #316) is in design phase and will adopt the same name; spec note locks the convention before two SDKs ship with divergent names.Ask
Add a one-paragraph spec note (probably in
core/conventions.mdor equivalent) reserving the key and documenting the round-trip semantics. Not changing wire payloads, not changing schemas. Just naming.