Skip to main content
AdCP 3.0 Proposal - This specification is under development for AdCP 3.0. Feedback welcome via GitHub Discussions.
Status: Request for Comments Last Updated: January 2026 The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

Abstract

The Property Protocol defines a standard Model Context Protocol (MCP) and Agent-to-Agent (A2A) interface for property identity, authorization, data provision, and selection. This protocol enables publishers to declare properties and authorized agents, data providers to offer property intelligence, and buyers to select compliant property sets.

Overview

The Property Protocol addresses four distinct concerns:
ConcernQuestionOwnerMechanism
Property IdentityWhat properties exist?Publishersadagents.json properties array
Sales AuthorizationWho can sell this property?Publishersadagents.json authorized_agents
Property DataWhat do we know about this property?Data providersGovernance agents via get_adcp_capabilities
Property SelectionWhich properties meet my requirements?BuyersProperty lists with filters
The first two are publisher-side declarations via adagents.json. The last two are buyer-side operations that consume property data from governance agents.

Property Data and Selection

Property data and selection use a stateful model:
  • Feature discovery: Agents advertise what they can evaluate via get_adcp_capabilities
  • Property list management: CRUD operations for managed property lists with filters
  • Brand manifests: Let agents automatically apply rules based on brand characteristics
  • Webhook notifications: Real-time updates when resolved lists change
  • Marketplace architecture: Multiple specialized agents as subscription services
All evaluation (scoring, filtering, discovery) happens implicitly when property lists are resolved via get_property_list.

Core Concepts

Request Roles and Relationships

Every governance request involves two key roles:

Orchestrator (Buyer Agent)

The platform or system making the API request to the governance agent. In AdCP documentation, this role is often called a “buyer agent” when operating in the media buying context.
  • Examples: DSP, trading desk platform, campaign management tool
  • Responsibilities: Makes API calls, handles authentication, manages the technical interaction
  • Account: Has technical credentials and API access to the governance agent

Principal

The entity on whose behalf the request is being made:
  • Examples: Advertiser (Nike), agency (Omnicom), brand team
  • Responsibilities: Owns the campaign objectives and policy requirements
  • Policies: May have custom thresholds, blocklists, or compliance requirements

Property Identification

Properties are identified using the standard AdCP property model:
{
  "property_type": "website",
  "name": "Example News",
  "identifiers": [
    { "type": "domain", "value": "example.com" }
  ],
  "supported_channels": ["display", "olv"]
}
Property types include: website, mobile_app, ctv_app, dooh, podcast, radio, streaming_audio. Properties may also declare supported_channels to indicate which advertising channels their inventory aligns with.

Property List References

For large property sets, use property list references instead of embedding properties:
{
  "property_list_ref": {
    "agent_url": "https://lists.example.com",
    "list_id": "premium_news_sites",
    "auth_token": "eyJhbGciOiJIUzI1NiIs..."
  }
}
The receiving agent fetches and caches the list independently, enabling:
  • Scale: Pass 50,000+ properties without payload bloat
  • Updates: Lists evolve without changing requests
  • Authorization: Token controls access to the list

Governance Agent Types

Compliance Agents

Specialized vendors providing property compliance intelligence:
  • Examples: Data integrity scoring, consent quality measurement
  • Business Model: Subscription or per-query pricing
  • Methodology: Published rubrics for transparency

Brand Safety Agents

Content classification and risk assessment:
  • Examples: Content categorization, brand safety scoring
  • Coverage: May specialize by channel or geography

Quality Agents

Performance and fraud measurement:
  • Examples: Viewability prediction, IVT detection
  • Integration: May correlate with campaign outcomes

Scoring and Data Privacy

Scores Are Internal

Critical design principle: Raw scores are NOT shared with buyers or downstream clients. This prevents data leakage. Governance agents maintain internal scoring models, but the protocol is designed around list management, not score exposure:
  • Buyers specify thresholds via feature_requirements (e.g., "min_value": 85)
  • Agents return pass/fail lists of properties that meet the thresholds
  • Raw scores never leave the governance agent
This design prevents:
  • Score enumeration attacks (running lists with different thresholds to reverse-engineer scores)
  • Competitive intelligence leakage
  • Data arbitrage where buyers resell scoring data

What Buyers Receive

When calling get_property_list, buyers receive a compact list of identifiers (not full property objects) for efficiency:
{
  "list_id": "pl_abc123",
  "identifiers": [
    { "type": "domain", "value": "bbc.co.uk" },
    { "type": "domain", "value": "theguardian.com" },
    { "type": "domain", "value": "ft.com" }
  ],
  "total_count": 847
}
Properties that pass the threshold are included. Properties that fail are excluded. No scores or property metadata are returned - just the identifiers needed for bid-time lookups.

Methodology Discovery

The get_adcp_capabilities task returns information about what features an agent evaluates and their methodology, but NOT the underlying scores:
{
  "features": [
    {
      "feature_id": "mfa_score",
      "name": "Made For Advertising Score",
      "type": "quantitative",
      "range": { "min": 0, "max": 100 },
      "methodology": "mfa_detection",
      "methodology_version": "v2.1",
      "methodology_url": "https://quality.example.com/methodology"
    }
  ]
}
This allows buyers to:
  • Understand what an agent measures
  • Compare methodologies across agents
  • Set appropriate thresholds
But they cannot retrieve the actual scores for individual properties.

Tasks

Discovery

get_adcp_capabilities

Discover what features a governance agent can evaluate. Use Cases:
  • Capability discovery: Understand what an agent can evaluate
  • Marketplace browsing: Compare features across agents
  • Integration planning: Know what filters are available before creating lists

Property List Management

create_property_list

Create a new property list with filters and optional brand manifest. Required Parameters:
  • At least one country in countries_all (ISO 3166-1 alpha-2 code)
  • At least one channel in channels_any (display, video, audio, etc.)
Base Properties: An array of property sources to evaluate. Each entry is a discriminated union with selection_type as the discriminator:
  • publisher_tags: { "selection_type": "publisher_tags", "publisher_domain": "...", "tags": [...] } - tags scoped to publisher
  • publisher_ids: { "selection_type": "publisher_ids", "publisher_domain": "...", "property_ids": [...] } - property IDs scoped to publisher
  • identifiers: { "selection_type": "identifiers", "identifiers": [...] } - no publisher context needed
  • Omitted: Query the agent’s entire property database
See the base-property-source schema for the full specification. Filter Logic (explicit in field names):
  • countries_all: Property must have feature data for ALL listed countries
  • channels_any: Property must support ANY of the listed channels
  • feature_requirements: Property must pass ALL requirements (AND)
Use Cases:
  • Define compliant property sets with filters (country, channel, feature thresholds)
  • Provide brand manifest for automatic rule application
  • Register webhook URL for change notifications

update_property_list

Modify an existing property list. Use Cases:
  • Add or remove properties from base list
  • Adjust filters based on campaign needs
  • Update webhook URL

get_property_list

Retrieve a property list with resolved properties. Use Cases:
  • Get the current list of compliant properties after filters applied
  • Cache resolved list for bid-time use
  • Retrieve updated list after webhook notification

list_property_lists

List all property lists accessible to the authenticated principal.

delete_property_list

Remove a property list.

Validation

validate_property_delivery

Validates delivery records against a property list to determine compliance. Closes the loop between “what I wanted” and “what I got.” Performs two independent validations:
  1. Property compliance: Is the identifier in the resolved property list?
  2. Supply path authorization: Was the sales agent authorized to sell that property? (optional, requires sales_agent_url)
Use Cases:
  • Post-campaign validation: Verify impressions landed on compliant properties
  • Supply path verification: Confirm sales agents were authorized by publishers
  • Real-time monitoring: Check compliance rate during campaign execution
  • Audit trails: Generate compliance reports for regulatory or brand safety reviews
Property Validation Statuses:
  • compliant: Identifier is in the resolved property list
  • non_compliant: Identifier is NOT in the resolved property list
  • not_covered: Identifier recognized but governance agent has no data for it (e.g., property too new)
  • unidentified: Identifier type not resolvable by this agent (e.g., detection failed, unsupported type)
Authorization Validation Statuses (when sales_agent_url provided):
  • authorized: Sales agent is listed in publisher’s adagents.json
  • unauthorized: Sales agent is NOT in publisher’s authorized_agents list
  • unknown: Could not fetch or parse adagents.json
Unverifiable Records: Both not_covered and unidentified records should be excluded when calculating compliance rates - you cannot penalize for detection gaps or coverage limitations. The distinction helps identify whether the gap is in the agent’s data coverage vs the identifier resolution. Response Format: The response returns raw counts (compliant, non_compliant, not_covered, unidentified impressions). Consumers calculate rates as needed. Governance agents may optionally include an aggregate field with computed metrics (score, grade, label) - the format and meaning are agent-specific.

Typical Flows

Property List Flow

Property lists enable buyers to define and manage compliant property sets:
  1. Create property list: Buyer defines list on governance agent with filters
  2. Resolve and iterate: Buyer calls get_property_list to see resolved properties
  3. Share list reference: Buyer provides list_id to orchestrator/seller
  4. Cache locally: Orchestrator/seller fetches and caches resolved properties
  5. Use at bid time: Orchestrator/seller uses local cache (no governance agent calls)
  6. Refresh periodically: Re-fetch based on cache_valid_until (typically 1-24 hours)
Important: Governance agents are NOT in the real-time bid path. All bid-time decisions use locally cached property sets.

Webhook and Caching Pattern

Webhooks provide notification that a property list has changed. The webhook payload contains a summary of changes, but you must call get_property_list to retrieve the actual updated properties.
┌─────────────────────────────────────────────────────────────────┐
│                     Webhook Flow                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. Governance agent re-evaluates properties (background)       │
│  2. Webhook fires with change summary (added/removed counts)    │
│  3. Recipient calls get_property_list to fetch updated list     │
│  4. Recipient updates local cache                               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
Best Practices for Downstream Consumers: Consumers of property lists (orchestrators, sellers, buyer agents) should implement at least one of these patterns:
  1. Webhook-driven updates (recommended): Register a webhook URL when creating the property list. Re-fetch via get_property_list when notified of changes.
  2. Polling with cache hints: Use cache_valid_until from get_property_list responses to schedule periodic re-fetches. Typical validity periods are 1-24 hours.
  3. Hybrid approach: Use webhooks for immediate updates, with polling as a fallback safety net.
Cache Expiry Guidance: Every get_property_list response includes:
  • resolved_at: When the list was evaluated
  • cache_valid_until: When consumers should consider the cache stale
{
  "resolved_at": "2026-01-04T10:00:00Z",
  "cache_valid_until": "2026-01-04T22:00:00Z"
}
Consumers MUST NOT use cached data beyond cache_valid_until without re-fetching.

Property Discovery Flow

  1. Define filters: Specify country, channel, quality thresholds when creating property list
  2. Resolve list: Call get_property_list with resolve=true to get matching properties
  3. Review candidates: Evaluate returned properties for fit
  4. Add to campaign: Include property list reference in media buy

Response Structure

All AdCP Governance responses follow a consistent structure:

Core Response Fields

  • message: Human-readable summary of the operation result
  • context_id: Session continuity identifier for follow-up requests
  • data: Task-specific payload (varies by task)

Protocol Transport

  • MCP: Returns complete response as flat JSON object
  • A2A: Returns as structured artifacts with message in text part, data in data part
  • Data Consistency: Both protocols contain identical AdCP data structures

Error Handling

Error Codes

  • PROPERTY_NOT_FOUND: Property identifier not recognized
  • PROPERTY_NOT_MONITORED: Governance agent doesn’t cover this property
  • POLICY_NOT_FOUND: Referenced policy doesn’t exist
  • LIST_ACCESS_DENIED: Cannot access property list (auth failed)
  • LIST_NOT_FOUND: Property list reference invalid
  • METHODOLOGY_NOT_SUPPORTED: Requested methodology version unavailable
  • PARTIAL_RESULTS: Some properties couldn’t be evaluated

Partial Success

For bulk operations, the response may include partial results:
{
  "message": "Evaluated 847 of 850 properties. 3 properties not in coverage.",
  "context_id": "ctx-gov-123",
  "scores": [...],
  "errors": [
    {
      "code": "PROPERTY_NOT_MONITORED",
      "property": { "identifiers": [{ "type": "domain", "value": "unknown.com" }] },
      "message": "Property not in monitoring coverage"
    }
  ]
}

Implementation Notes

Caching Architecture

Governance decisions are highly cacheable:

Orchestrator-Side Caching

  • Score cache: Store scores with TTL from valid_until field
  • Decision cache: Pre-compute pass/fail for campaigns
  • List cache: Cache property lists from property_list_ref

Agent-Side Caching

  • Profile cache: Maintain pre-computed property profiles
  • Methodology cache: Cache scoring algorithm results

Performance Requirements

OperationTarget Latency
Single property score< 100ms
Bulk scoring (100 properties)< 2s
Filter decision (cached)< 5ms
Property discovery< 5s

Multi-Agent Strategies

Orchestrators may consult multiple governance agents:
  1. Primary + Validation: Use primary agent, validate with secondary
  2. Specialization: Route by property type to specialist agents
  3. Consensus: Require multiple agents to agree
  4. Competitive: Track agent accuracy, weight by performance

Agent Discovery

There are two complementary discovery mechanisms:

Publisher-Side Discovery via adagents.json

Publishers declare which governance agents have data about their properties using the property_features field in adagents.json:
{
  "property_features": [
    {
      "url": "https://api.sustainability-vendor.example",
      "name": "Sustainability Vendor",
      "features": ["carbon_score", "green_media_certified"],
      "publisher_id": "pub_12345"
    },
    {
      "url": "https://api.quality-vendor.example",
      "name": "Quality Vendor",
      "features": ["mfa_score", "ad_density", "page_speed"]
    }
  ]
}
This solves the discovery problem: buyers don’t need to query every possible governance agent. Instead, they read property_features from the publisher’s adagents.json to find which agents have relevant data. See the adagents.json Tech Spec for the complete discovery workflow.

Agent-Side Discovery via agent-card.json

Governance agents expose capabilities via .well-known/agent-card.json:
{
  "name": "Example Compliance Provider",
  "url": "https://compliance.example.com",
  "capabilities": {
    "tasks": [
      "get_adcp_capabilities",
      "create_property_list",
      "get_property_list",
      "update_property_list",
      "delete_property_list",
      "list_property_lists",
      "validate_property_delivery"
    ],
    "protocols": ["MCP", "A2A"],
    "schema_version": "v1"
  },
  "methodology": {
    "documentation_url": "https://compliance.example.com/methodology",
    "scoring_frameworks": ["data_integrity_index", "brand_safety_score"],
    "coverage": {
      "property_types": ["website", "mobile_app", "ctv_app"],
      "jurisdictions": ["GDPR", "CCPA", "COPPA"]
    }
  }
}

Detailed Capability Discovery

Use get_adcp_capabilities for detailed capability discovery:
{
  "tool": "get_adcp_capabilities",
  "arguments": {}
}
Returns the specific features the agent can evaluate (mfa_score, carbon_score, brand_risk, etc.).

Marketplace Architecture

The Property Protocol enables a marketplace of specialized data agents:
┌─────────────────────────────────────────────────────────────────────────┐
│                         SELLER AGENT (DSP/SSP)                          │
│  "Give me the compliant property list for this campaign"                │
└───────────────────────────────┬─────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│                    BUYER AGENT (implements Property Protocol)           │
│  - Exposes: get_adcp_capabilities, get_property_list, webhooks         │
│  - Source of truth for final compliant list                             │
│  - Intersects results from specialized agents                           │
└───────────────────────────┬─────────────────────────────────────────────┘

        ┌───────────────────┼───────────────────┐
        ▼                   ▼                   ▼
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│ Quality Agent │   │ Sustainability│   │ Suitability   │
│               │   │    Agent      │   │    Agent      │
├───────────────┤   ├───────────────┤   ├───────────────┤
│ Features:     │   │ Features:     │   │ Features:     │
│ mfa_score     │   │ carbon_score  │   │ content_cat   │
│ ad_density    │   │ climate_risk  │   │ brand_risk    │
│ page_speed    │   │ green_media   │   │ sentiment     │
├───────────────┤   ├───────────────┤   ├───────────────┤
│ Subscription  │   │ Subscription  │   │ Subscription  │
└───────────────┘   └───────────────┘   └───────────────┘

Key Principles

  1. Buyer agent is source of truth: The buyer agent aggregates data from multiple specialized governance agents
  2. Seller sees one interface: Sellers interact only with the buyer agent using standard Property Protocol
  3. Subscription model: Each specialized agent is a paid service with its own features and coverage
  4. Webhook-driven updates: Specialized agents notify the buyer agent when property evaluations change

Multi-Agent Orchestration

A buyer agent can distribute a master property list to multiple specialized agents:
# Buyer agent creates variants on each specialized agent
consent_list = consent_agent.create_property_list(
    name="Q1 Campaign - Consent",
    base_properties=master_list,
    brand_manifest=brand_manifest
)
# Configure webhook for updates
consent_agent.update_property_list(
    list_id=consent_list.list_id,
    webhook_url="https://buyer.example.com/webhooks/consent"
)

scope3_list = scope3_agent.create_property_list(
    name="Q1 Campaign - Sustainability",
    base_properties=master_list,
    brand_manifest=brand_manifest
)
scope3_agent.update_property_list(
    list_id=scope3_list.list_id,
    webhook_url="https://buyer.example.com/webhooks/scope3"
)

# Buyer agent intersects filtered results
def on_list_changed(event):
    consent_props = consent_agent.get_property_list(consent_list.list_id, resolve=True)
    scope3_props = scope3_agent.get_property_list(scope3_list.list_id, resolve=True)

    # Intersection = properties that pass ALL governance agents
    compliant_props = intersect(consent_props, scope3_props)

    # Update buyer agent's exposed list
    update_compliant_list(compliant_props)

Brand Manifest

Instead of specifying complex filters, buyers provide a brand manifest:
{
  "brand_manifest": {
    "brand_name": "ToyBrand",
    "industry": "toys",
    "target_audience": "children_under_13",
    "content_adjacency": ["kids_family", "education"],
    "excluded_content": ["violence", "adult"]
  }
}
Each governance agent interprets the manifest according to their domain expertise:
  • Consent agent: Applies COPPA requirements for children_under_13
  • Brand safety agent: Filters to kids_family content, excludes violence/adult
  • Sustainability agent: Applies any green media requirements
The buyer doesn’t need to know the specific rules - they declare who they are, and agents figure out what applies.

Integration with Media Buy Protocol

Property Lists in Media Buys

The Media Buy Protocol accepts property list references:
{
  "task": "create_media_buy",
  "arguments": {
    "packages": [{
      "property_list_ref": {
        "agent_url": "https://governance.example.com",
        "list_id": "approved_q1_campaign",
        "auth_token": "..."
      }
    }]
  }
}

Policy Compliance

Media buys can reference governance policies via property list references:
{
  "compliance_requirements": {
    "property_list_ref": {
      "agent_url": "https://compliance.example.com",
      "list_id": "pl_q1_compliant",
      "auth_token": "eyJhbGciOiJIUzI1NiIs..."
    }
  }
}

Best Practices

  1. Cache aggressively: Property scores change slowly; cache for hours/days
  2. Bulk where possible: Use batch operations for planning, not per-property calls
  3. Pre-compute decisions: Build pass/fail lookups before bid-time
  4. Monitor coverage: Track which properties agents don’t cover
  5. Log methodology versions: For audit trails, record which scoring version was used
  6. Handle partial results: Not all properties will be scorable; plan for gaps

Next Steps