Skip to content

Reserve ctx_metadata as adapter-internal round-trip key on resource objects #3640

Description

@bokelley

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.enhancementNew feature or requestspec / protocol

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions