Skip to content

RFC: audience activation method (Snowflake / LiveRamp / direct API / clean rooms) #4324

Description

@bokelley

Background

The audience-targeting capability today describes what kinds of identifiers a seller accepts (supported_identifier_types, supported_uid_types, supports_platform_customer_id) but says nothing about how the data moves. AdCP-native sync, TMP identity match, cloud bucket dropoff, vendor-mediated dataset queries, clean room matches — these are the integration realities that determine whether activation is one config switch or three weeks of engineering work for a buyer.

The gap

A buyer with a Snowflake-based audience pipeline and a seller that only takes direct-API audience sync are technically compatible (both speak sync_audiences) and practically incompatible without rebuilding the buyer's pipeline. Today this is discovered at integration time, or worse, at activation time when a campaign starts and audiences don't sync.

Today's nearest fields:

  • audience_targeting.supported_identifier_types — kinds of IDs (email, phone).
  • audience_targeting.supported_uid_types — UID frameworks (RampID, UID2, MAID).
  • audience_targeting.supports_platform_customer_id — platform-native customer IDs.

None answer "where does the data move and how."

Proposed addition

A new audience_activation block on core/product.json and a supported_activation_methods summary on the audience_targeting capability. Each activation method declares a pattern plus pattern-specific fields. Two patterns are AdCP-canonical and first-class; three cover non-AdCP integration realities.

AdCP-canonical patterns (preferred)

sync_audiences — bare. Seller declares "I accept audience pushes via the AdCP sync_audiences tool." Any AdCP-speaking buyer can use it.

tmp_identity_match — declares specific buyer agents the seller integrates with for TMP runtime identity match. Seller must list each buyer agent it has configured. The integration isn't generic; the seller has set up TMP calls to specific buyer agents.

{ "pattern": "sync_audiences" }
{ "pattern": "tmp_identity_match", "buyer_agent": { "agent_url": "https://buyer.scope3.com" } }
{ "pattern": "tmp_identity_match", "buyer_agent": { "agent_url": "https://buyer.interchange.com" } }

Non-AdCP patterns (legacy / vendor-specific)

cloud_bucket — raw cloud storage push or pull. Requires direction and cloud_provider (a BrandRef).

{ "pattern": "cloud_bucket", "direction": "push_to_seller",  "cloud_provider": { "domain": "amazon.com" } }
{ "pattern": "cloud_bucket", "direction": "pull_from_buyer", "cloud_provider": { "domain": "amazon.com" } }
{ "pattern": "cloud_bucket", "direction": "push_to_seller",  "cloud_provider": { "domain": "cloud.google.com" } }

direction is push_to_seller (buyer writes to seller-hosted bucket) or pull_from_buyer (seller reads from buyer-hosted bucket). These have different security/legal posture and aren't interchangeable.

dataset_query — vendor-mediated query access (Snowflake Secure Data Sharing, Databricks Delta Sharing, BigQuery authorized views). Seller queries a dataset the buyer makes available through the vendor's sharing mechanism. Requires vendor (BrandRef).

{ "pattern": "dataset_query", "vendor": { "domain": "snowflake.com" } }
{ "pattern": "dataset_query", "vendor": { "domain": "databricks.com" } }

clean_room — privacy-preserving match. Neither party sees the other's raw rows. Requires vendor (BrandRef). The vendor identifies the clean room product (AMC = amazon.com, Snowflake DCR = snowflake.com, LiveRamp clean room = liveramp.com, etc.).

{ "pattern": "clean_room", "vendor": { "domain": "amazon.com" } }
{ "pattern": "clean_room", "vendor": { "domain": "snowflake.com" } }
{ "pattern": "clean_room", "vendor": { "domain": "liveramp.com" } }
{ "pattern": "clean_room", "vendor": { "domain": "habu.com" } }

Why vendor identity is a BrandRef domain (not an enum)

The schema already uses BrandRef ({ domain, brand_id? }) for vendor identity in measurement reporting ((vendor.domain, vendor.brand_id, metric_id)). Reusing it here:

  • New entrants (Alibaba Cloud, OpenAI, Databricks Delta Share, vendor-X clean room) declare a domain and they're in. No spec PR, no enum bottleneck.
  • TMP unifies cleanly: a buyer agent's agent_url is the natural identity for tmp_identity_match integrations.
  • Verifiable: a vendor's brand.json can attest to its activation role; buyers can confirm declarations.

cloud_provider is a separate slot from vendor because cloud providers (AWS, GCP, Azure) are infrastructure platforms, not products. AMC is vendor: amazon.com because it's a specific Amazon product; raw S3 push is cloud_provider: amazon.com because it's the cloud's storage primitive. The pattern field disambiguates ("Amazon" means different things in clean_room vs cloud_bucket context).

Per-product and per-seller declarations

Per product (core/product.json):

"audience_activation": {
  "methods": [ /* array of activation method entries */ ],
  "preferred_method": { /* optional, single entry */ },
  "notes": "free-text caveats"
}

Required when the product accepts buyer audiences; absent otherwise.

Per seller (get-adcp-capabilities-response.jsonaudience_targeting):

"supported_activation_methods": [ /* union of per-product methods */ ]

Source of truth is per-product. The seller-wide field is a union for fast-fail discovery: a buyer can read this once and skip the catalog walk if there's no overlap with their pipeline.

Filter integration

Add audience_activation_method to core/product-filters.json so get_products can narrow results to activatable inventory using existing filter infrastructure. No new filter mechanism — just a new key. Sellers exclude products whose audience_activation.methods doesn't intersect the filter; buyers detect via filter_diagnostics.excluded_by.

Validation rules

pattern required fields forbidden fields
sync_audiences (none) all others
tmp_identity_match buyer_agent.agent_url vendor, cloud_provider, direction
cloud_bucket direction, cloud_provider vendor, buyer_agent
dataset_query vendor cloud_provider, buyer_agent, direction
clean_room vendor cloud_provider, buyer_agent, direction

Open questions for WG

  1. SFTP / non-cloud legacy paths. Not modeled in this proposal. SFTP doesn't fit cloud_bucket (no cloud provider). Three options: (a) drop entirely, since AdCP sync_audiences is the canonical push and the spec shouldn't bless legacy paths; (b) add a file_transfer pattern with a transport field; (c) document SFTP as out-of-band custom integration with no schema entry. Lean (a).
  2. Reporting symmetry. The same pattern + vendor/cloud_provider model maps directly to delivery reporting back to the buyer ("seller pushes reports to buyer's S3" vs "seller publishes via Snowflake share"). Sibling RFC for reporting_method writes itself with the same shape. Should land separately to keep WG agendas tight.
  3. Per-pricing-option variance. Activation method may vary by pricing tier (Snowflake share carries data-egress fees). v1 keeps at the product level; revisit if real cases show variance.
  4. Identifier-type intersection. A product might support dataset_query for emails but sync_audiences for MAIDs. v1 ignores this; extend audience_activation.methods[] entry to optionally carry identifier_types: [] if real cases need it.
  5. Vendor verification. A seller declaring vendor: liveramp.com should be confirmable by reading liveramp.com's brand.json. Out of scope for v1 schema, but worth flagging — same trust model as the broader AdCP vendor pattern.

Out of scope

  • Activation pricing (lives in pricing-options).
  • Authentication / credential exchange specifics per method.
  • Buyer-side spend-uplift preferences ("I'll spend more with sellers supporting X") — separate artifact, lives near buy-terms negotiation.

Related

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.media-buyIssue concerns the media-buy protocol domainneeds-wg-reviewBlocked on a working-group decision — surface in WG meeting agendasrfcProtocol change — auto-adds to roadmap boardsignalsIssue concerns the signals protocol domain

    Type

    No type

    Projects

    Status
    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions