> ## Documentation Index
> Fetch the complete documentation index at: https://agenticadvertisingorg-snap-format-preview-links.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Signals Specification

> Formal AdCP signals protocol specification. Transport requirements, get_signals and activate_signal task schemas, conformance criteria, error handling, activation key security, and RFC 2119 requirements.

**Status**: Request for Comments
**Last Updated**: January 25, 2026

This document defines the Signals Protocol specification. 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](https://www.rfc-editor.org/rfc/rfc2119).

## Abstract

The Signals Protocol defines a standard interface for AI-powered signal discovery, activation, and management systems. This protocol enables AI assistants to help marketers discover, activate, and manage data signals (audiences, contextual, geographical, temporal, and multi-dimensional data) through natural language interactions.

## Protocol Overview

The Signals Protocol provides:

* Natural language signal discovery based on marketing objectives
* Multi-platform signal discovery in a single request
* Signal activation for specific platforms and accounts
* Transparent pricing with CPM and revenue share models
* Signal size reporting with unit types (individuals, devices, households)

## Transport Requirements

Signal agents MUST support at least one of the following transports:

| Transport | Protocol               | Description                         |
| --------- | ---------------------- | ----------------------------------- |
| MCP       | Model Context Protocol | Tool-based interaction via JSON-RPC |
| A2A       | Agent-to-Agent         | Message-based interaction           |

Signal agents SHOULD support MCP as the preferred transport.

Signal agents MUST declare Signals Protocol support via `get_adcp_capabilities`:

```json theme={null}
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/protocol/get-adcp-capabilities-response.json",
  "status": "completed",
  "adcp": {
    "major_versions": [2],
    "idempotency": { "supported": true, "replay_ttl_seconds": 86400 }
  },
  "supported_protocols": ["signals"]
}
```

## Core Concepts

### Request Roles

Every signal request involves two roles:

* **Orchestrator**: The platform making the API request (e.g., a buyer agent or AI assistant)
* **Account**: The commercial relationship on whose behalf the request is made. See [Accounts Protocol](/docs/accounts/overview).

### Signal Agent Types

**Private Signal Agents** — owned by a single account with exclusive access:

* Signal agents MUST return `REFERENCE_NOT_FOUND` for unauthorized accounts — the
  same response as "agent does not exist." Distinguishing "exists but unauthorized"
  from "does not exist" would enable cross-tenant enumeration of private agents.
  See the uniform-response MUST in
  [error-handling.mdx](/docs/building/implementation/error-handling) for the full
  set of observable channels that MUST match on both paths.
* Signal agents MUST NOT expose private signals across accounts

**Marketplace Signal Agents** — license signal data to multiple accounts:

* Signal agents MUST support public wholesale feed access without account registration
* Signal agents SHOULD support account-personalized wholesale feed views for registered accounts

### Identifiers

* **`signal_agent_segment_id`**: Opaque signal handle issued by the signal source. Signals Protocol responses MUST return this for each signal and orchestrators MUST use it in `activate_signal` requests. For seller-offered media-buy signal targeting, buyers use `signal_ref` as the named signal reference and include `signal_agent_segment_id` only when the selected product option exposes a distinct execution handle.

* **`activation_key`**: Key for external deployment targeting. Signal agents MUST return this when `is_live: true` AND the caller has access to the deployment. Orchestrators MUST use this for platform or destination targeting (not `signal_agent_segment_id`). For seller-offered signals selected on a sales-agent media buy, use `packages[].targeting_overlay.signal_targeting_groups`; include `activation_key` only when the seller requires a prior activation key.

### Governance metadata

Signal definitions MAY include `restricted_attributes` and `policy_categories` fields to enable structural governance matching. Data providers SHOULD declare these so governance agents can deterministically evaluate compliance rather than inferring sensitivity from signal names.

* **`restricted_attributes`**: Array of GDPR Article 9 special category values this signal touches. Governance agents SHOULD prefer declared attributes over semantic inference.
* **`policy_categories`**: Array of policy category IDs this signal is sensitive for. Governance agents match these against a plan's `policy_categories` to flag sensitive data usage.

See [Declaring governance metadata](/docs/signals/data-providers#declaring-governance-metadata) for implementation details.

### Enrichment and progressive disclosure

Rich definition fields such as `taxonomy.values[]`, `taxonomy.value_mappings[]`, `segmentation_criteria`, `onboarder`, and `modeling.disclosure.jurisdictions[]` describe the authoritative signal definition. They are not required to be repeated in every discovery listing.

Signal agents SHOULD treat `get_signals` as a discovery and availability surface. For broad search results and wholesale feed pages, agents SHOULD return compact listings with stable identity, display metadata, pricing, deployment status, and cache validators or disclosure pointers when available. For provider-published public signals, `signal_ref` is the definition pointer: orchestrators fetch the provider's `/.well-known/adagents.json` (following `authoritative_location` when present) and select the matching `signals[].id`. Large taxonomies, long segmentation criteria, and jurisdiction-specific disclosure text SHOULD be fetched from that authoritative signal definition or from declared URLs such as `taxonomy.ref`, `criteria_url`, and `modeling.disclosure.jurisdictions[].disclosure_url`.

When the provider file includes the existing `adagents.json` `catalog_etag`, or the HTTP response includes `ETag` or `Last-Modified`, orchestrators SHOULD cache the fetched `adagents.json` document by resolved authoritative URL plus that validator, then resolve `signal_ref.signal_id` within the cached document. Clients MUST NOT key signal-definition caches by validator alone. Use `taxonomy.etag` for taxonomy documents that have their own freshness validator. Agents MAY include inline excerpts for review, ranking, or lookup-by-reference flows, but SHOULD avoid duplicating full external resources across every item in a large `get_signals` response.

Orchestrators that need richer metadata inline MAY set `fields` on `get_signals`, using the same response-projection pattern as `get_products.fields`, to request specific listing or definition fields such as `taxonomy`, `data_sources`, `methodology`, `modeling`, `countries`, `consent_basis`, or `data_subject_rights`. Agents SHOULD honor requested fields for exact lookup, refinement, small custom-signal result sets, and private/source-native signals that do not have a public `adagents.json` definition. `fields` is a projection request, not an entitlement grant; agents MAY redact requested definition fields unless the caller is authorized for the underlying lineage, methodology, and rights-routing metadata. When a seller or federating agent projects another provider's `consent_basis` or `art9_basis` into a `get_signals` row, the value remains the provider-declared signal-definition posture; the seller MUST NOT rewrite it into the seller's own processing basis. For broad discovery and wholesale pages, agents MAY still return compact pointers instead of inlining large definition resources.

### Definition enrichment fields

Signal definitions MAY carry additional fields for transparency, governance, and review:

* **Taxonomy metadata**: `taxonomy.ref`, `taxonomy.values[]`, `taxonomy.value_mappings[]`, and `taxonomy.parent_match_behavior` describe how the signal maps to an external or provider-owned taxonomy. These fields do not change package targeting grammar.
* **Source and methodology disclosure**: `data_sources`, `methodology`, `segmentation_criteria`, `criteria_url`, `refresh_cadence`, `lookback_window`, and `onboarder` describe how the segment was compiled. Offline and public-record source categories require `onboarder`.
* **Modeling disclosure**: `modeling` is required when `methodology` is `modeled` or `audience_expansion` is `true`. Required modeling disclosures must name the jurisdictions where the disclosure applies.
* **Jurisdiction and privacy metadata**: `countries`, GDPR-scoped `consent_basis`, `restricted_attributes`, `policy_categories`, and `art9_basis` let governance agents evaluate use constraints structurally. Federating agents that surface a peer's signal MUST treat the peer's `countries[]` as an upper bound, re-check it against the buyer's intended deployment countries, and only apply narrower local policy.
* **Data-subject-rights routing**: `data_subject_rights.channels[]` declares where access, erasure, objection, portability, or rectification requests route for this signal. At least one channel must support one or more of access, erasure, or objection. `response_sla_days` is signal-scoped because custom/private signals and upstream-specific routes may not share a public provider-wide policy surface. Global Privacy Control support is not declared on signal definitions, and consumers MUST NOT infer GPC handling from `data_subject_rights`.

### Runtime validation notes

The Signal Definition schema uses JSON Schema draft-07 `if`/`then` and `contains`
for constraints that many SDK generators do not preserve. Consumers and SDKs
SHOULD implement runtime guards for these cases:

* `value_type: "categorical"` with `taxonomy` requires `taxonomy.value_mappings`.
* `audience_scope: "single_domain"` requires `originating_domain`.
* `methodology: "modeled"` or `audience_expansion: true` requires `modeling`.
* Offline or public-record `data_sources[]` require `onboarder`.
* `data_subject_rights.channels[]` must include at least one channel supporting one or more of access, erasure, or objection.

`art9_basis` is policy-required rather than schema-required because Article 9
applicability depends on jurisdiction and use. Governance agents SHOULD run a
runtime check: when `restricted_attributes[]` is non-empty and the planned use
touches Article 9 jurisdictions, require `art9_basis` or raise a review issue
before activation.

## Tasks

The Signals Protocol defines two task schemas. All conformant Signals Protocol
agents implement `get_signals` for discovery. Agents that claim the
marketplace activation specialism, advertise activation/deactivation, or return
signals that require buyer-managed activation implement `activate_signal` as the
activation lifecycle surface.

### get\_signals

**Schema**: [`get-signals-request.json`](https://adcontextprotocol.org/schemas/v3/signals/get-signals-request.json) / [`get-signals-response.json`](https://adcontextprotocol.org/schemas/v3/signals/get-signals-response.json)

**Reference**: [`get_signals` task](/docs/signals/tasks/get_signals)

Discover signals matching campaign criteria.

**Requirements:**

* Orchestrators MUST include `signal_spec`, `signal_refs`, or deprecated `signal_ids`
* Signal agents MUST return all required fields per response schema
* Signal agents MUST include `activation_key` when `is_live: true` AND caller has deployment access

### activate\_signal

**Schema**: [`activate-signal-request.json`](https://adcontextprotocol.org/schemas/v3/signals/activate-signal-request.json) / [`activate-signal-response.json`](https://adcontextprotocol.org/schemas/v3/signals/activate-signal-response.json)

**Reference**: [`activate_signal` task](/docs/signals/tasks/activate_signal)

Activate a signal for use on a decisioning platform. `activate_signal` is required for agents claiming `signal_marketplace`, advertising activation/deactivation, or returning signals that require buyer-managed activation; discovery-only owned-signal agents are not required to expose it.

**Requirements:**

* Orchestrators MUST include `signal_agent_segment_id` and `destinations`
* On success, signal agents MUST return a `deployments` array with `is_live` for each deployment
* Signal agents MUST return `activation_key` when `is_live: true` AND caller has deployment access
* On failure, signal agents MUST return an `errors` array (with no `deployments` array)

## Error Handling

Signal agents MUST return errors using the [standard AdCP error schema](/docs/building/implementation/error-handling).

Signal agents MUST use Signals Protocol error codes as defined in the [Error Handling Reference](/docs/building/implementation/error-handling).

## Security Considerations

### Transport Security

All Signals Protocol communications MUST use HTTPS with TLS 1.2 or higher.

### Authentication

* Orchestrators MUST authenticate with signal agents using valid credentials
* Signal agents MUST validate credentials before processing requests
* Signal agents SHOULD use account context to determine catalog access level

### Activation Key Security

* Signal agents MUST only return `activation_key` to authenticated callers with deployment access
* Signal agents MUST NOT return activation keys for deployments the caller cannot access

### Data Minimization

* Signal agents MUST NOT return signals the authenticated agent or account is not authorized to access

## Conformance

### Signal Agent Conformance

A conformant baseline Signals Protocol agent MUST:

1. Support at least one specified transport (MCP or A2A)
2. Implement `get_signals` per schema
3. Return required fields as defined in response schemas
4. Use specified error codes
5. Enforce access control for private signals and, when activation is supported,
   activation keys

Agents claiming a marketplace activation specialism or otherwise advertising
activation support MUST also implement `activate_signal` per schema. Discovery-
only owned-signal agents MAY conform to the Signals Protocol baseline without
implementing `activate_signal`.

### Orchestrator Conformance

A conformant Signals Protocol orchestrator MUST:

1. Authenticate with signal agents
2. Include required fields as defined in request schemas
3. Handle async activation responses when using `activate_signal`
4. Use `activation_key` for external deployment targeting when activation is in
   scope, and use package-level `signal_targeting_groups` for seller-offered
   signal selection on sales-agent media buys

When a seller-offered signal should be applied only to specific packages on a sales-agent buy, orchestrators SHOULD carry that selection in `create_media_buy.packages[].targeting_overlay.signal_targeting_groups`, including the selected signal `pricing_option_id` when required and the selected `signal_ref`. `get_signals` is the broader discovery surface, while the selected product's inline `signal_targeting_options` when present and `signal_targeting_rules` govern buy-time eligibility and pricing; wholesale products can omit inline options and rely on `get_signals` for candidate discovery. `included_signals` is descriptive only: it identifies signals already bundled into or planned into the product, but does not make them selectable. If the product option or `get_signals` result exposes a separate `signal_agent_segment_id` required by the seller, buyers echo it as an execution handle; otherwise `signal_ref` is sufficient. This is the package-level binding; `audience_include` and `audience_exclude` remain scoped to buyer-managed audiences from `sync_audiences`.

## Implementation Notes

### Multi-Platform Discovery

Orchestrators MAY request signals across multiple platforms in a single `get_signals` call.

Signal agents SHOULD return deployment information for all requested platforms.

### Activation Timing

Signal activation is typically asynchronous:

* Simple activations: 1-2 hours
* Complex deployments: up to 24-48 hours

Orchestrators MUST NOT assume immediate availability after activation request.

### Destination Type Selection

The `activate_signal` request supports two destination types. The choice depends on the buyer's execution path:

* Orchestrators buying through a Sales Agent SHOULD use `type: "agent"` destinations with the SA's URL. The SA handles downstream platform coordination — which DSP it uses is an implementation detail.
* Orchestrators buying directly on a DSP SHOULD use `type: "platform"` destinations. The orchestrator is responsible for ensuring the activation platform matches where campaigns will run.
* Signal marketplace agents MUST support both destination types per the destination schema.

### Creative signal fan-out and trafficking compatibility

`build_creative` may fan out over `signal_conditions` ([#5240](https://github.com/adcontextprotocol/adcp/issues/5240)) — a keep-all production axis that produces one distinct creative group per signal condition (e.g. a rain creative AND a sun creative). Each produced group is tagged with the `signal_condition` (a `SignalTargeting`) it is FOR.

**Trafficking-compatibility invariant (normative).** A creative built FOR one signal condition MUST NOT serve into a package targeting an incompatible condition. The sales agent enforces this **reject-at-trafficking** on `create_media_buy` / `sync_creatives`: assigning a creative whose `signal_condition` is incompatible with the package's signal targeting is rejected with `SIGNAL_TARGETING_INCOMPATIBLE`. This is NOT enforced at `build_creative` — at the build layer the signal pointer is advisory (the buyer-attached-input contract); enforcement lives at the trafficking boundary.

**Matching.** Compatibility is matched on shared `signal_ref` identity — namespaced `signal_agent_segment_id` / data-provider-scoped `signal_ref` is the primary path, categorical `{signal_id, value}` the fallback. For `value_type: numeric` the comparison is range-overlap (WG-open: range-overlap vs exact-match). This is the **same** `signal_ref` identity used by `packages[].targeting_overlay.signal_targeting_groups` on `create_media_buy`, which is what makes the cross-agent match structurally possible without a shared-taxonomy registry.

## Schema Reference

| Schema                                                                                                                    | Description               |
| ------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
| [`signals/get-signals-request.json`](https://adcontextprotocol.org/schemas/v3/signals/get-signals-request.json)           | get\_signals request      |
| [`signals/get-signals-response.json`](https://adcontextprotocol.org/schemas/v3/signals/get-signals-response.json)         | get\_signals response     |
| [`signals/activate-signal-request.json`](https://adcontextprotocol.org/schemas/v3/signals/activate-signal-request.json)   | activate\_signal request  |
| [`signals/activate-signal-response.json`](https://adcontextprotocol.org/schemas/v3/signals/activate-signal-response.json) | activate\_signal response |
| [`core/deployment.json`](https://adcontextprotocol.org/schemas/v3/core/deployment.json)                                   | Deployment target         |
| [`core/activation-key.json`](https://adcontextprotocol.org/schemas/v3/core/activation-key.json)                           | Activation key            |
