> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# activate_signal

> activate_signal is the AdCP task for pushing audience segments to DSPs and sales agents. Supports async activation, deactivation for data governance, and returns platform-specific activation keys.

**Task**: Activate a signal for use on a specific platform/account.

**Response Time**: Minutes to days (asynchronous with potential human-in-the-loop)

**Request Schema**: [`https://adcontextprotocol.org/schemas/3.3.0-beta.1/signals/activate-signal-request.json`](https://adcontextprotocol.org/schemas/3.3.0-beta.1/signals/activate-signal-request.json)
**Response Schema**: [`https://adcontextprotocol.org/schemas/3.3.0-beta.1/signals/activate-signal-response.json`](https://adcontextprotocol.org/schemas/3.3.0-beta.1/signals/activate-signal-response.json)

The `activate_signal` task handles the entire activation lifecycle, including:

* Initiating the activation request
* Monitoring activation progress
* Returning the final deployment status

## Request Parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `idempotency_key` | string | Yes | Client-generated unique key for this request. Prevents duplicate activations on retries. MUST be unique per (seller, request) pair. Min 16 chars. See [Idempotency](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/by-layer/L1/security.md#idempotency) for normative semantics. |
| `signal_agent_segment_id` | string | Yes | Opaque signal handle from [`get_signals`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/signals/tasks/get_signals) for the signal to activate |
| `action` | string | No | `"activate"` (default) or `"deactivate"`. Deactivating removes segments from downstream platforms for data governance compliance (GDPR, CCPA). |
| `destinations` | Destination\[] | Yes | Target destination(s) for activation (see Destination Object below) |
| `account` | [AccountRef](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/by-layer/L2/accounts-and-agents.md#account-references) | No | Account for this activation. Associates with a commercial relationship established via [`sync_accounts`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/accounts/tasks/sync_accounts). |
| `pricing_option_id` | string | Yes (if signal has pricing options) | The pricing option selected from `pricing_options` in the [`get_signals`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/signals/tasks/get_signals) response. Records the buyer's pricing commitment at activation time. Pass this same value in subsequent [`report_usage`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/accounts/tasks/report_usage) calls. |
| `governance_context` | string | Conditional | Opaque approval context returned by [`check_governance`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/governance/campaign/tasks/check_governance) for this activation. Required when the activation account has a registered governance agent. |

## Governance

Signal activation is a spend-commit event when the selected signal carries activation, usage, or CPM fees. For governed accounts, the buyer-side orchestrator MUST call [`check_governance`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/governance/campaign/tasks/check_governance) before `activate_signal` with `purchase_type: "signal_activation"` and a normalized activation payload that includes the spend basis, such as `total_budget` or `budget`.

When `check_governance` approves the activation, pass the returned `governance_context` into `activate_signal`. If the account has a governance agent registered via [`sync_governance`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/accounts/tasks/sync_governance) and the request omits a valid `governance_context`, the signal agent MUST reject the request with [`PERMISSION_DENIED`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/verification/compliance-catalog#error-code-permission-denied). If `check_governance` denies the activation, the buyer MUST NOT call `activate_signal`.

### Destination Object

Each deployment target uses a `type` field to discriminate between platform-based and agent-based deployments:

| Parameter | Type | Required | Description |
| - | - | - | - |
| `type` | string | Yes | Discriminator: "platform" for DSPs, "agent" for sales agents |
| `platform` | string | Conditional\* | Platform identifier (e.g., 'the-trade-desk', 'amazon-dsp'). Required when type="platform" |
| `agent_url` | string (URI) | Conditional\* | URL identifying the sales agent. Required when type="agent" |
| `account` | string | No | Account identifier on the platform or agent |
| `delivery_method` | object | No | **Experimental** (`signals.delivery_methods`). Operator pin for the delivery rail on `type="agent"` destinations — `pattern` plus optional `vendor`. See [Delivering membership to agent destinations](#delivering-membership-to-agent-destinations-experimental). |

\*`platform` is required when `type="platform"`, `agent_url` is required when `type="agent"`.

**Activation Keys**: If the authenticated caller has access to any of the deployment targets in the request, the signal agent will include `activation_key` in the response for those deployments.

**Permission Model**: The signal agent determines key inclusion based on the caller's authentication and authorization. For example:

* A sales agent receives keys for deployments matching its `agent_url`
* A buyer with credentials for multiple DSP platforms receives keys for all those deployments
* Access is determined by the signal agent's permission system, not by flags in the request

## Delivering membership to agent destinations (experimental)

> [!NOTE]
>
> Experimental. Signal agents that declare `signals.delivery_methods` MUST list `signals.delivery_methods` in `experimental_features`. See [Experimental status](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/reference/experimental-status.md).

For `type: "platform"` destinations the provider-to-platform rails are pre-integrated and out of view. For `type: "agent"` destinations there is no assumed integration, so how licensed membership reaches the seller would otherwise be bespoke per provider. This section standardizes that leg using the same pattern vocabulary sellers already use to declare how audience data reaches them ([`audience_activation`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/media-buy/product-discovery/media-products#audience-activation)).

This is the provider-initiated leg: the operator directs a signal agent to deliver **provider-licensed** membership. Buyer-owned data the buyer moves itself binds through [`sync_audiences` external sources](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/media-buy/task-reference/sync_audiences#external-audience-sources-experimental) instead. Seller-controlled sourcing of a data marketplace's segments into the seller's own taxonomy is out of protocol; it surfaces only as the seller's own signal options.

### Declaring delivery methods

A signal agent lists the rails it can deliver on in [`signals.delivery_methods`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/protocol/get_adcp_capabilities#signals), each entry a [`core/signal-delivery-method.json`](https://adcontextprotocol.org/schemas/3.3.0-beta.1/core/signal-delivery-method.json):

```json theme={null}
{
  "signals": {
    "delivery_methods": [
      { "pattern": "sync_audiences" },
      { "pattern": "platform_distribution", "vendor": { "domain": "activation-hub.example" } },
      { "pattern": "dataset_query", "vendor": { "domain": "data-cloud.example" } }
    ]
  }
}
```

Entries use the send-side reading of the activation-method patterns: `sync_audiences` pushes membership to the destination's `sync_audiences` task; `platform_distribution` initiates distribution on that vendor's rails; `dataset_query` publishes a share on that vendor for the destination to read; `clean_room` lands output in that vendor's room; `file_transfer` writes to the destination's bucket on that vendor's storage. Receiver-specific fields (`destination_ref`, `consumer_identities`, `bind_expiry_days`) are **not** declared by the signal agent. They belong to the destination and are resolved at activation time from the destination's own declaration. `tmp_identity_match` is not a delivery pattern: it resolves identity at request time and no membership file ever moves, so there is nothing to deliver.

The capability is optional. A signal agent that serves only platform destinations omits it.

### Rail selection

For each `type: "agent"` destination the signal agent reads the destination's declared methods from the seller's [`get_adcp_capabilities`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/protocol/get_adcp_capabilities) (`media_buy.audience_targeting.supported_activation_methods`), using the destination's `account` where the seller scopes the declaration to an account. It intersects them with its own `delivery_methods`. A method matches on **pattern and vendor** (`vendor.domain`, lowercase; `brand_id` only when both sides set it). `file_transfer` also requires the same `transport`, and the signal agent takes the sending role: it is compatible with a destination `directions` of `buyer_to_seller` or one that is absent. A `clean_room` match counts only when the destination's output-rail pattern (`dataset_query` or `platform_distribution`) intersects too. Receiver-specific fields the seller has not yet established (`destination_ref`, `consumer_identities`) are resolved from account setup; when they are not yet resolvable the destination fails with [`ACCOUNT_SETUP_REQUIRED`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/verification/compliance-catalog#error-code-account-setup-required).

Any rail in the intersection is eligible, and selection is the signal agent's discretion. The operator MAY pin the rail by setting `delivery_method` (`pattern` and optionally `vendor`) on the destination entry; it is the cost-control and reproducibility lever. A pin is a MUST-use: the signal agent uses a matching rail or fails that destination, and never falls back to another rail. Buyers MUST check that the signal agent lists `signals.delivery_methods` before sending a pin, because a legacy agent silently ignores unknown destination fields. An agent that implements this surface but does not list the capability MUST reject the request with an `errors[]` response carrying [`UNSUPPORTED_FEATURE`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/verification/compliance-catalog#error-code-unsupported-feature) and `field: "destinations[i].delivery_method"`.

A signal agent that declares `delivery_methods` MUST deliver to agent destinations only over a rail in the intersection. If there is none, including when the destination has declared no methods (an undeclared destination has no address to deliver to; the seller must declare one), that destination fails with `UNSUPPORTED_FEATURE` rather than activating over a bespoke route. A signal agent that does not declare `delivery_methods` keeps its existing agent-destination behavior; the capability is not mandatory for every signal agent.

A failed destination does not fail the others. Report it as a deployment with `delivery_status: "failed"` and a `delivery_error` whose `field` names the destination entry (`destinations[0]`, or `destinations[0].delivery_method` for a pin mismatch). When every requested destination fails this way the signal agent MUST return the `errors[]` arm instead, so a buyer reading `status: "completed"` never mistakes total failure for success. `failed` is terminal for that attempt; retry with a new `idempotency_key`.

Delivery cost is absorbed in the signal's price: provider-initiated delivery uses the existing `pricing_options` and `pricing_option_id`, with no separate rail fee.

### Arrival, addressability, and match outcome

Three questions are reported separately on each agent deployment:

| Question | Field | Values |
| - | - | - |
| Has membership arrived? | `delivery_status` | `awaiting_read`, `delivered`, `failed` |
| Can the signal be targeted? | `is_live` (with `activation_key`) | boolean |
| How well did it match? | `match_status` (optionally `matched_count`, `effective_match_rate`, `match_rate_basis`, `audience_size`) | the [audience status](https://adcontextprotocol.org/schemas/3.3.0-beta.1/enums/audience-status.json) values `sync_audiences` reports |

`delivered` is not an addressability claim, and coverage on the seller's inventory is the match rate against the seller's own identity graph. The signal agent populates all of these from what its rail reports back. For pull rails (`dataset_query`, `platform_distribution`, `clean_room`) `delivered` means the destination has read the membership, as attested by the rail or the seller. For push rails (`sync_audiences`, `file_transfer`) it means the destination accepted the write. State moves `awaiting_read` → `delivered` or `failed`. Agents SHOULD set `is_live: true` only once `delivered`, and include `delivery_error` when, and only when, the state is `failed`. When a delivery window is declared on the destination (`bind_expiry_days` for `platform_distribution`), reaching it moves the deployment to `failed`.

`match_status` and the counts are optional; `audience_size` (a range with stated precision, the shape `sync_audiences` adopted for range-only platforms) and `match_rate_basis` let those platforms relay a match outcome without inventing a point count and use the same vocabulary on every rail, so they are not rail-dependent. They appear only when the destination reports them back to the signal agent (for example through the `sync_audiences` response); absence means not reported, never zero. `too_small` implies `is_live: false`.

Distribution can take days, so `awaiting_read` is a normal, long-lived state. The first response returns the current state, and the task is complete at that point, so later state changes do not fire a task webhook. Read them through [`get_signals`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/signals/tasks/get_signals), which returns the same deployment objects. `action: "deactivate"` removes the deployment and carries no delivery state.

Each agent deployment may also carry a `delivery` descriptor shaped like an [external audience source](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/media-buy/task-reference/sync_audiences.md#external-audience-sources-experimental) (`kind: "dataset"` with `vendor` and `locator`, or `kind: "platform_segment"` with `vendor` and `segment_ref`). It identifies what the signal agent shipped and is the join key on the destination side. It explains how membership arrives; `activation_key` remains how to target it. Rails with no vendor-addressable artifact (`sync_audiences`, `file_transfer`) omit it. It is a reference, never a credential; unlike an audience source it does not carry `access_expires_at`.

A segment delivered this way surfaces on the seller as **signal inventory**, targetable through signal targeting and reported through signal deployment status. It is not a buyer audience in `sync_audiences` discovery, including when the rail is the destination's own `sync_audiences` task: the seller MUST keep provider-licensed membership out of buyer-audience discovery.

### Example

```json theme={null}
{
  "tool": "activate_signal",
  "arguments": {
    "idempotency_key": "6f1c2b9e-3a47-4d0a-9c55-0b7e1f2a8d11",
    "signal_agent_segment_id": "luxury_auto_intenders",
    "pricing_option_id": "po_cpm_usd",
    "destinations": [{
      "type": "agent",
      "agent_url": "https://wonderstruck.salesagents.com",
      "delivery_method": {
        "pattern": "platform_distribution",
        "vendor": { "domain": "activation-hub.example" }
      }
    }]
  }
}
```

Initial response, with membership shipped and awaiting the seller's read:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "deployments": [{
    "type": "agent",
    "agent_url": "https://wonderstruck.salesagents.com",
    "is_live": false,
    "delivery_status": "awaiting_read",
    "delivery": {
      "kind": "platform_segment",
      "vendor": { "domain": "activation-hub.example" },
      "segment_ref": "seg_88213"
    },
    "estimated_activation_duration_minutes": 2880
  }]
}
```

After the seller reads and matches:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "deployments": [{
    "type": "agent",
    "agent_url": "https://wonderstruck.salesagents.com",
    "is_live": true,
    "delivery_status": "delivered",
    "delivery": {
      "kind": "platform_segment",
      "vendor": { "domain": "activation-hub.example" },
      "segment_ref": "seg_88213"
    },
    "match_status": "ready",
    "matched_count": 412000,
    "effective_match_rate": 0.58,
    "activation_key": { "type": "key_value", "key": "audience_segment", "value": "luxury_auto_intenders_v2" },
    "deployed_at": "2026-10-07T09:14:00Z"
  }]
}
```

No rail in common with the destination:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "deployments": [{
    "type": "agent",
    "agent_url": "https://wonderstruck.salesagents.com",
    "is_live": false,
    "delivery_status": "failed",
    "delivery_error": {
      "code": "UNSUPPORTED_FEATURE",
      "message": "Destination declares no delivery rail in common with this signal agent.",
      "field": "destinations[0]"
    }
  }]
}
```

## Response Structure

All AdCP responses include:

* **message**: Human-readable summary of the activation status
* **context\_id**: A2A conversation correlation; compatibility metadata only on MCP
* **data**: Task-specific payload (see Response Data below)

The response structure is identical across protocols, with only the transport wrapper differing:

* **MCP**: Returns complete response as flat JSON
* **A2A**: Returns as artifacts with message in text part, data in data part

For asynchronous operations like activation, both protocols support:

* **Status tracking**: Check completion status via task\_id
* **Progress updates**: Real-time updates on activation progress

## Response Data

```json theme={null}
{
  "deployments": [
    {
      "type": "platform",
      "platform": "string",
      "account": "string",
      "activation_key": {
        "type": "segment_id",
        "segment_id": "string"
      },
      "estimated_activation_duration_minutes": "number",
      "deployed_at": "string"
    }
  ],
  "errors": [
    {
      "code": "string",
      "message": "string",
      "field": "string",
      "suggestion": "string",
      "details": {}
    }
  ]
}
```

### Field Descriptions

* **deployments**: Array of deployment results for each deployment target
  * **platform**: Platform identifier for DSPs (either platform or agent\_url will be present)
  * **agent\_url**: URL identifying the deployment agent (either platform or agent\_url will be present)
  * **account**: Account identifier if applicable
  * **activation\_key**: The key to use for targeting (see Activation Key below). Only present if the authenticated caller has access to this deployment.
  * **estimated\_activation\_duration\_minutes**: Estimated completion time for async operations
  * **deployed\_at**: ISO 8601 timestamp when activation completed
  * **delivery\_status**, **delivery**, **delivery\_error**, **match\_status**, **matched\_count**, **effective\_match\_rate** (agent deployments, experimental): provider-initiated delivery arrival, descriptor, failure reason, and optional match outcome. See [Delivering membership to agent destinations](#delivering-membership-to-agent-destinations-experimental).
* **errors**: Optional array of errors and warnings encountered during activation
  * **code**: Standardized error code for programmatic handling
  * **message**: Human-readable error description with context
  * **field**: Field path associated with the error (optional)
  * **suggestion**: Suggested fix for the error (optional)
  * **details**: Additional activation-specific error details (optional)

### Activation Key Object

The activation key represents how to use the signal on a deployment target. It can be either a segment ID or a key-value pair:

**Segment ID format (typical for DSP platforms):**

```json theme={null}
{
  "type": "segment_id",
  "segment_id": "ttd_segment_12345"
}
```

**Key-Value format (typical for sales agents):**

```json theme={null}
{
  "type": "key_value",
  "key": "audience_segment",
  "value": "luxury_auto_intenders"
}
```

### Using Activation Keys

The activation key tells the buyer how to reference the signal on the destination. The execution path depends on the destination type:

**Platform destinations** — The `activation_key` contains a `segment_id`, a platform-native identifier. The signal agent pushed segment data to the DSP; the buyer references this key when configuring campaign targeting on that platform. The buyer is responsible for ensuring the activation platform matches where it will run campaigns.

**Agent destinations** — The `activation_key` confirms the signal is live on the sales agent. The SA records the activation internally and can apply signal-based targeting when fulfilling media buys through [`create_media_buy`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/media-buy/task-reference/create_media_buy). When the seller exposes selectable signals through inline `Product.signal_targeting_options` or through [`get_signals`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/signals/tasks/get_signals) for wholesale products that omit inline options, the buyer selects those signals in `packages[].targeting_overlay.signal_targeting_groups`, carrying the selected `signal_ref`, `pricing_option_id` when required, and any separate seller execution handle required by the product option or signal result. The buyer does not need to know which DSP the SA uses — downstream platform coordination is the SA's responsibility.

**Choosing a destination type**: Use `type: "platform"` when buying directly on a DSP. Use `type: "agent"` when buying through a Sales Agent — the SA coordinates its own DSP targeting as an implementation detail.

## Protocol-Specific Examples

The AdCP payload is identical across protocols. Only the request/response wrapper differs.

### MCP Request - Sales Agent Activation

```json theme={null}
{
  "tool": "activate_signal",
  "arguments": {
    "signal_agent_segment_id": "luxury_auto_intenders",
    "pricing_option_id": "po_cpm_usd",
    "destinations": [{
      "type": "agent",
      "agent_url": "https://wonderstruck.salesagents.com"
    }]
  }
}
```

### MCP Response - Synchronous (Key-Value)

Immediate response with activation key:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "message": "Signal successfully activated on Wonderstruck sales agent",
  "context_id": "ctx-signals-123",
  "deployments": [{
    "type": "agent",
    "agent_url": "https://wonderstruck.salesagents.com",
    "is_live": true,
    "activation_key": {
      "type": "key_value",
      "key": "audience_segment",
      "value": "luxury_auto_intenders_v2"
    },
    "deployed_at": "2025-01-15T14:30:00Z"
  }]
}
```

### MCP Request - DSP Platform Activation

```json theme={null}
{
  "tool": "activate_signal",
  "arguments": {
    "signal_agent_segment_id": "luxury_auto_intenders",
    "pricing_option_id": "po_cpm_usd",
    "destinations": [{
      "type": "platform",
      "platform": "the-trade-desk",
      "account": "agency-123-ttd"
    }]
  }
}
```

### MCP Response - Asynchronous (Segment ID)

Initial response:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "message": "Initiating activation of 'Luxury Auto Intenders' on The Trade Desk",
  "context_id": "ctx-signals-123",
  "deployments": [{
    "type": "platform",
    "platform": "the-trade-desk",
    "account": "agency-123-ttd",
    "is_live": false,
    "estimated_activation_duration_minutes": 30
  }]
}
```

After polling for completion:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "message": "Signal successfully activated on The Trade Desk",
  "context_id": "ctx-signals-123",
  "deployments": [{
    "type": "platform",
    "platform": "the-trade-desk",
    "account": "agency-123-ttd",
    "is_live": true,
    "activation_key": {
      "type": "segment_id",
      "segment_id": "ttd_agency123_lux_auto"
    },
    "deployed_at": "2025-01-15T14:30:00Z"
  }]
}
```

### A2A Request

#### Natural Language Invocation

Text-only invocation requires a separate generic A2A interface whose Agent
Card does not mark the AdCP v3 profile as required. It is not an AdCP profile
invocation.

#### Explicit Skill Invocation

```javascript theme={null}
await a2a.send({
  message: {
    messageId: crypto.randomUUID(),
    role: "ROLE_USER",
    parts: [{
      data: {
        skill: "activate_signal",
        input: {
          idempotency_key: crypto.randomUUID(),
          signal_agent_segment_id: "luxury_auto_intenders",
          pricing_option_id: "po_cpm_usd",
          destinations: [{
            type: "platform",
            platform: "the-trade-desk",
            account: "agency-123-ttd"
          }]
        }
      }
    }]
  }
});
```

### A2A Response

A non-streaming `SendMessage` response selects the completed Task branch. A
client that needs transport progress uses the official `SendStreamingMessage`
or `SubscribeToTask` operation and consumes `StreamResponse` SSE frames.

```json theme={null}
{
  "task": {
    "id": "task-signal-001",
    "contextId": "ctx-signals-123",
    "status": { "state": "TASK_STATE_COMPLETED" },
    "artifacts": [{
      "artifactId": "artifact-signal-activation-abc123",
      "name": "signal_activation_result",
      "parts": [
        { "text": "Signal successfully activated on The Trade Desk" },
        { "data": {
          "status": "completed",
          "deployments": [{
            "type": "platform",
            "platform": "the-trade-desk",
            "account": "agency-123-ttd",
            "is_live": true,
            "activation_key": {
              "type": "segment_id",
              "segment_id": "ttd_agency123_lux_auto"
            },
            "deployed_at": "2025-01-15T14:30:00Z"
          }]
        } }
      ]
    }]
  }
}
```

### Protocol Transport

* **MCP**: Returns task\_id for polling-based asynchronous operation tracking or webhook-based push notifications
* **A2A**: Returns the typed result in a completed Task; clients may opt into the official streaming operations for transport progress
* **Data Consistency**: Both protocols contain identical AdCP data structures and version information

### Webhook Support

For long-running activations (when initial response is `submitted`), configure a webhook to receive the complete response when activation completes:

```javascript theme={null}
const response = await session.call('activate_signal',
  {
    signal_agent_segment_id: "luxury_auto_intenders",
    pricing_option_id: "po_cpm_usd",
    destinations: [{
      type: "platform",
      platform: "the-trade-desk",
      account: "agency-123-ttd"
    }]
  },
  {
    webhook_url: "https://buyer.com/webhooks/adcp/activate_signal/agent_id/op_id",
    webhook_auth: { type: "bearer", credentials: "secret-token" }
  }
);
```

When activation completes, you receive the full `activate_signal` response:

```http theme={null}
POST /webhooks/adcp/activate_signal/agent_id/op_id HTTP/1.1
Content-Type: application/json
Authorization: Bearer secret-token

{
  "deployments": [{
    "type": "platform",
    "platform": "the-trade-desk",
    "account": "agency-123-ttd",
    "activation_key": {
      "type": "segment_id",
      "segment_id": "ttd_agency123_lux_auto"
    },
    "deployed_at": "2025-01-15T14:30:00Z"
  }]
}
```

See **[Webhooks](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/by-layer/L3/webhooks.md)** for complete details on webhook configuration and reliability.

## Scenarios

### Async Activation - Initial Response (Pending)

**Message**: "I've initiated activation of 'Luxury Automotive Context' on PubMatic for account brand-456-pm. This typically takes about 60 minutes. I'll monitor the progress and notify you when it's ready to use."

**Complete Response**:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "message": "I've initiated activation of 'Luxury Automotive Context' on PubMatic for account brand-456-pm. This typically takes about 60 minutes. I'll monitor the progress and notify you when it's ready to use.",
  "context_id": "ctx-signals-def456",
  "deployments": [{
    "type": "platform",
    "platform": "pubmatic",
    "account": "brand-456-pm",
    "is_live": false,
    "estimated_activation_duration_minutes": 60
  }]
}
```

### Async Activation - Final Response (Deployed)

**Message**: "Excellent! The 'Luxury Automotive Context' signal is now live on PubMatic. You can start using it immediately with the activation key provided. The activation completed faster than expected - just 52 minutes."

**Complete Response**:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "message": "Excellent! The 'Luxury Automotive Context' signal is now live on PubMatic. You can start using it immediately with the activation key provided. The activation completed faster than expected - just 52 minutes.",
  "context_id": "ctx-signals-def456",
  "deployments": [{
    "type": "platform",
    "platform": "pubmatic",
    "account": "brand-456-pm",
    "is_live": true,
    "activation_key": {
      "type": "segment_id",
      "segment_id": "pm_brand456_peer39_lux_auto"
    },
    "deployed_at": "2025-01-15T14:30:00Z"
  }]
}
```

### Sync Activation - Sales Agent (Immediate)

**Message**: "Signal successfully activated on Wonderstruck sales agent. Use the key-value pair in your targeting configuration."

**Complete Response**:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "message": "Signal successfully activated on Wonderstruck sales agent. Use the key-value pair in your targeting configuration.",
  "context_id": "ctx-signals-ghi789",
  "deployments": [{
    "type": "agent",
    "agent_url": "https://wonderstruck.salesagents.com",
    "is_live": true,
    "activation_key": {
      "type": "key_value",
      "key": "audience_segment",
      "value": "luxury_auto_context_v2"
    },
    "deployed_at": "2025-01-15T14:31:00Z"
  }]
}
```

### Success with Warnings

**Message**: "Successfully activated 'Luxury Automotive Context' on PubMatic, but noted some configuration issues. The signal is live and ready to use, though performance may be sub-optimal until the account settings are updated."

**Complete Response**:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "completed",
  "message": "Successfully activated 'Luxury Automotive Context' on PubMatic, but noted some configuration issues. The signal is live and ready to use, though performance may be sub-optimal until the account settings are updated.",
  "context_id": "ctx-signals-def456",
  "deployments": [{
    "type": "platform",
    "platform": "pubmatic",
    "account": "brand-456-pm",
    "is_live": true,
    "activation_key": {
      "type": "segment_id",
      "segment_id": "pm_brand456_peer39_lux_auto"
    },
    "deployed_at": "2025-01-15T14:30:00Z"
  }]
}
```

> [!NOTE]
>
> Warnings about suboptimal configuration are conveyed in the `message` field. The `errors` array is reserved for actual failures — the activate\_signal response uses a strict success/error discriminated union where `deployments` and `errors` are mutually exclusive.

### Error Response (Failed)

**Message**: "I couldn't activate the signal on PubMatic. Your account 'brand-456-pm' doesn't have permission to use Peer39 data. Please contact your PubMatic account manager to enable Peer39 access, then we can try again."

**Complete Response**:

```json theme={null}
{
  "$schema": "/schemas/3.3.0-beta.1/signals/activate-signal-response.json",
  "status": "failed",
  "message": "I couldn't activate the signal on PubMatic. Your account 'brand-456-pm' doesn't have permission to use Peer39 data. Please contact your PubMatic account manager to enable Peer39 access, then we can try again.",
  "context_id": "ctx-signals-def456",
  "errors": [
    {
      "code": "DEPLOYMENT_UNAUTHORIZED",
      "message": "Account brand-456-pm not authorized for Peer39 data on PubMatic",
      "field": "deployment.account",
      "suggestion": "Contact your PubMatic account manager to enable Peer39 data access for your account",
      "details": {
        "account_id": "brand-456-pm",
        "deployment_url": "https://pubmatic.com",
        "data_provider": "peer39",
        "required_permission": "third_party_data_access"
      }
    }
  ]
}
```

## Error Codes

### Activation Errors

* [`REFERENCE_NOT_FOUND`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/verification/compliance-catalog#error-code-reference-not-found): Referenced `signal_agent_segment_id` doesn't exist or is not accessible to the calling account (`error.field` identifies the failing parameter)
* `ACTIVATION_FAILED`: Could not activate signal for unspecified reasons
* `ALREADY_ACTIVATED`: Signal already active on the specified platform/account
* `DEPLOYMENT_UNAUTHORIZED`: Can't deploy to platform/account due to permissions
* `INVALID_PRICING_MODEL`: Requested pricing model not available for this signal
* [`UNSUPPORTED_FEATURE`](https://docs.adcontextprotocol.org/dist/docs/3.3.0-beta.1/building/verification/compliance-catalog#error-code-unsupported-feature): An agent destination shares no delivery rail with the signal agent, or none matches the `delivery_method` pin (experimental; reported per destination as `delivery_error`)

### Configuration Warnings

* `SUBOPTIMAL_CONFIGURATION`: Signal activated but account settings may impact performance
* `SLOW_ACTIVATION`: Activation taking longer than expected but still in progress
* `FREQUENCY_CAP_RESTRICTIVE`: Signal activated but account frequency caps may reduce performance

## Error Handling Philosophy

### Status vs Errors

* **Task Status**: Indicates overall activation outcome (`deployed`, `failed`, etc.)
* **Errors Array**: Contains specific issues, warnings, and remediation steps
* **Partial Success**: Signal can be `deployed` while still having warnings in `errors` array

### Error Types

* **Fatal Errors**: Prevent activation (status = `failed`)
* **Warnings**: Signal activates successfully but with caveats (status = `deployed` + errors)
* **Configuration Issues**: Non-blocking problems that affect performance

## Usage Notes

1. **Account-Specific**: Include the `account` parameter for account-specific activations
2. **Platform-Wide**: Omit the `account` parameter for platform-wide activations
3. **Async Operation**: This is a long-running task that provides status updates
4. **Monitoring**: Use task ID to monitor progress via polling or SSE
5. **Idempotent**: Safe to retry if activation fails

## Implementation Guide

### Generating Activation Messages

The `message` field should provide clear status updates and actionable information:

```python theme={null}
def generate_activation_message(status, signal_info, request):
    if status == "pending":
        return f"I've initiated activation of '{signal_info.name}' on {request.platform} for account {request.account}. This typically takes about {signal_info.estimated_duration} minutes. I'll monitor the progress and notify you when it's ready to use."
    
    elif status == "processing":
        progress_details = get_progress_details()
        time_remaining = calculate_time_remaining()
        return f"Good progress on the activation. {progress_details}. About {time_remaining} minutes remaining."
    
    elif status == "deployed":
        actual_duration = calculate_actual_duration()
        timing_note = "faster than expected" if actual_duration < signal_info.estimated_duration else "as expected"
        return f"Excellent! The '{signal_info.name}' signal is now live on {request.platform}. You can start using it immediately in your campaigns with the ID '{signal_info.platform_id}'. The activation completed {timing_note} - just {actual_duration} minutes."
    
    elif status == "failed":
        error_explanation = explain_error_in_context(error_code)
        next_steps = get_remediation_steps(error_code)
        return f"I couldn't activate the signal on {request.platform}. {error_explanation}. {next_steps}"
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.