> ## 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.

# Creative capabilities on sales agents

> Sales agents in AdCP implement the Creative Protocol alongside Media Buy for inline creative management and generative ad formats.

Sales agents can implement the Creative Protocol alongside the Media Buy Protocol. When they do, a single agent endpoint handles both media buying and creative management — the buyer doesn't need to discover and connect to a separate service.

This is the common case for sellers that generate creatives at serve time, manage a creative library internally, or offer format-specific creative services as part of their ad product.

## How it works

A sales agent declares Creative Protocol support in `get_adcp_capabilities`:

```json theme={null}
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/protocol/get-adcp-capabilities-response.json",
  "status": "completed",
  "adcp": {
    "major_versions": [3],
    "idempotency": { "supported": true, "replay_ttl_seconds": 86400 }
  },
  "supported_protocols": ["media_buy", "creative"],
  "account": {
    "supported_billing": ["operator", "agent"]
  },
  "media_buy": {
    "features": {
      "inline_creative_management": true
    }
  },
  "creative": {
    "has_creative_library": true,
    "supports_generation": true,
    "supports_transformation": false,
    "supports_compliance": false
  }
}
```

Note that `inline_creative_management` (a media buy feature for attaching creatives to packages at buy time), Creative Protocol support, and `creative.has_creative_library` are distinct declarations. A sales agent can accept inline package creatives without a creative library, can host a library without inline package uploads, or can support both paths.

`inline_creative_management` allows attaching creatives directly to packages in `create_media_buy` and `update_media_buy` — the creative travels with the buy or package update. Creative Protocol support (`"creative"` in `supported_protocols`) means the agent implements creative tasks such as `build_creative`, `list_creative_formats`, or [`sync_creatives`](/docs/creative/task-reference/sync_creatives), depending on its creative capability flags. A reusable creative library is advertised specifically by `creative.has_creative_library: true`. A sales agent might support inline creative management without implementing a library (the buyer supplies package-scoped creative bodies with the media-buy request), or host a library without inline management (creatives are synced separately via `sync_creatives` before being assigned to packages).

The buyer calls all tasks — media buy and creative — on the same agent URL. The protocol the task belongs to determines the schema, not the type of agent.

## Buyer creative path selection

Buyers choose the creative delivery path from the media-buy inline flag and the Creative Protocol library capability:

| `creative.has_creative_library` | `media_buy.features.inline_creative_management` | Buyer behavior                                                                                                                                                                                                                                                                       |
| ------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `true`                          | Absent or `false`                               | Use Creative Protocol tasks such as `sync_creatives`, then assign stored creatives with `packages[].creative_assignments`.                                                                                                                                                           |
| Absent or `false`               | `true`                                          | Use `packages[].creatives` inline on `create_media_buy` and `update_media_buy`. Do not call `sync_creatives`; the seller has not advertised a creative library.                                                                                                                      |
| `true`                          | `true`                                          | Both paths are available. Use inline creatives for single-use package assets or immediate replacement, and `sync_creatives` plus `creative_assignments` for reusable library assets. Inline creatives become library creatives because the seller has advertised a creative library. |
| Absent or `false`               | Absent or `false`                               | The seller has not advertised creative delivery over AdCP. Buyers SHOULD NOT send `packages[].creatives` or `packages[].creative_assignments` unless another seller-specific extension explicitly defines that behavior.                                                             |

When `inline_creative_management` is true and `creative.has_creative_library` is absent or false, `packages[].creatives` is the advertised creative surface. The seller may store those assets only as part of the media buy or package; buyers should not expect `list_creatives`, `sync_creatives`, or later `creative_assignments` reuse to work.

Inline-only approval-state readback is package-scoped. `get_media_buys` surfaces the package's currently assigned inline creative approvals through `packages[].creative_approvals[]` (`creative_id`, `approval_status`, and optional `rejection_reason`), but it does not return the full creative body, placement routing, weights, or prior revisions. Buyers using inline-only sellers should retain the submitted creative manifest or asset payload on their side if they need to inspect or resubmit it later.

## Available creative tasks

When a sales agent declares `"creative"` in `supported_protocols`, it can implement any Creative Protocol task:

| Task                    | When to implement                                                                                                                  |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `list_creative_formats` | Always — buyers need to discover supported formats                                                                                 |
| `sync_creatives`        | When the agent hosts a creative library. Sales agents SHOULD support the `assignments` field for bulk creative-to-package mapping. |
| `list_creatives`        | When buyers need to browse the library                                                                                             |
| `build_creative`        | When the agent generates or transforms creatives                                                                                   |
| `preview_creative`      | When the agent can render previews                                                                                                 |
| `get_creative_delivery` | When the agent can report variant-level delivery data                                                                              |

These are the same tasks a standalone creative agent implements. The difference is operational, not protocol-level: the buyer doesn't need to discover and connect to a separate service.

Sales agents that already implement the [accounts protocol](/docs/accounts/overview) for media buys do not need additional account setup for creative tasks — the same account covers both protocols.

## Stored creative adapter handoff

When a buyer uploads a creative through `sync_creatives`, then later attaches it to a package using `creative_assignments` in `create_media_buy` or `update_media_buy`, the AdCP protocol surface carries only one identifier: `creative_id`. The buyer chooses it when the creative is created or synced, and later reuses that same value to assign the stored creative without resending the asset bytes.

The `id` field in the example below is not a second buyer-provided AdCP identifier. It is a seller-side adapter alias copied from `creative_id` for implementation layers that already use a generic asset `id`. AdCP does not require any upstream ad server, retail-media platform, or seller system of record to use this object. This shape is implementation guidance for seller SDKs, fixtures, and adapters that choose to transform an AdCP stored creative into an internal asset payload.

When an implementation exposes a URL-backed stored creative to an adapter layer, the adapter-facing object SHOULD preserve both identifier spellings plus the portable metadata needed to traffic the asset.

Adapter-facing internal object (not an AdCP request or response shape):

```json test=false theme={null}
{
  "id": "cr_acme_spring_mrec",
  "creative_id": "cr_acme_spring_mrec",
  "name": "Acme Corp spring MREC",
  "format_id": {
    "agent_url": "https://creative.adcontextprotocol.org",
    "id": "display_300x250"
  },
  "format_kind": "image",
  "asset_type": "image",
  "url": "https://cdn.acme.example/creative/spring-mrec.png",
  "width": 300,
  "height": 250
}
```

`creative_id` is the canonical AdCP stored creative identifier. `id` is an adapter-compatibility alias for generic asset contracts that expect an `id` field. Implementations SHOULD populate both with the same value when transforming a stored creative into an adapter asset; adapters should prefer `creative_id` when both are present. On the AdCP wire, buyers send only `creative_id` in `creative_assignments[]`. The adapter-only `id` alias is internal compatibility data, not a second buyer-supplied identifier; sellers MUST ignore it if present on input.

The URL-backed path above is the portable adapter handoff. Snippet-backed or inline-content-backed stored creatives, such as HTML snippets, third-party tags, or seller-rendered brief content, require explicit adapter support because the transformation depends on that adapter's trafficking model. Docs and SDK scaffolds SHOULD NOT imply that every adapter receives fields such as `snippet`, `content`, or `media_url` unless that adapter's contract actually declares and handles them.

## Creative review

Sales agents that receive creatives — whether via inline attachment in `create_media_buy` or via `sync_creatives` — may perform creative review before serving. This mirrors real publisher and SSP workflows where creatives are scanned for policy compliance, malware, or brand safety violations.

Creative review status is surfaced at two levels:

* **Creative library**: For sellers that advertise `creative.has_creative_library: true`, the `status` field on each creative in [`list_creatives`](/docs/creative/task-reference/list_creatives) uses the creative status enum: `processing`, `pending_review`, `approved`, `rejected`, or `archived`.
* **Package level**: The `approval_status` field on each creative in [`get_media_buys`](/docs/media-buy/task-reference/get_media_buys) responses uses the creative approval status enum: `pending_review`, `approved`, or `rejected`. Rejected creatives include a `rejection_reason` with a human-readable explanation.

A creative may be `approved` in the library but `rejected` at the package level if it violates placement-specific policies (e.g., a video creative on an audio-only placement).

Buyers SHOULD poll `list_creatives` or `get_media_buys` after syncing or submitting a media buy with new creatives, especially for publishers with strict creative policies. For inline-only sellers, `get_media_buys` is the approval-state readback surface.

For generative formats where the seller generates at serve time, creative review applies to the brief and brand identity rather than individual creatives. The seller validates that the brief's constraints and brand assets meet its policies before generation begins.

**Platform and community guidelines**: Social platforms, UGC sites, and community-driven publishers often enforce content policies beyond standard ad policy (e.g., community standards, promoted content guidelines, category-specific restrictions). These platform-specific policies are surfaced through the same `rejection_reason` field — the buyer does not need a separate mechanism to handle them. When a creative is rejected for a community guideline violation, the `rejection_reason` explains what policy was violated so the buyer can fix and re-submit.

### Implementation checklist for generative creative

Sales agents offering generative creative should:

1. **Declare capabilities** in `get_adcp_capabilities`:
   * `supports_generation: true` in creative capabilities
   * `"creative"` in `supported_protocols`
   * `inline_creative_management: true` if creatives travel with the media buy

2. **Define generative formats** via `list_creative_formats` where `format_id.agent_url` points to your own agent. Include descriptive format names and asset requirements (at minimum a `brief` asset).

3. **Implement `preview_creative`** — return representative previews for pre-flight review. Support `context_description` inputs so buyers can simulate different serve-time conditions. For conversational formats, include `interactive_url` for sandbox testing.

4. **Implement `get_creative_delivery`** — return variant manifests showing what was generated and served. Include `generation_context` (context\_type, topic, device\_class) and delivery metrics per variant. Plan for variant retention: retain at least 90 days of variant data for post-flight audit.

5. **Validate briefs at buy time** — when a buyer submits a brief in `create_media_buy`, validate that the brief's constraints (brand identity, guardrails, required disclosures) are compatible with your generation capabilities. Reject with a clear error if not.

6. **Handle creative review for briefs** — for generative formats, review applies to the brief and brand identity rather than individual creatives. Communicate review status via `approval_status` on the package in `get_media_buys`.

## Generative formats on sales agents

A seller that generates creatives at serve time — contextual ads, page-matched display, AI-generated native — hosts its own generative format. The `format_id.agent_url` points to the sales agent itself:

```json theme={null}
{
  "format_id": {
    "agent_url": "https://ads.seller-example.com",
    "id": "contextual_display_generative"
  },
  "name": "Contextual display (AI-generated)",
  "type": "display",
  "description": "Display ads generated at serve time based on page context and brand brief"
}
```

The buyer discovers this format through `list_creative_formats` on the sales agent, then provides a brief when creating the media buy:

```json theme={null}
{
  "packages": [{
    "product_id": "premium_display",
    "pricing_option_id": "cpm_standard",
    "budget": 50000,
    "creatives": [{
      "creative_id": "brand_contextual_brief",
      "name": "Q2 contextual campaign brief",
      "format_id": {
        "agent_url": "https://ads.seller-example.com",
        "id": "contextual_display_generative"
      },
      "assets": {
        "brief": {
          "content": "Highlight our sustainability story. Match tone to editorial context."
        }
      }
    }]
  }]
}
```

The seller generates creatives at serve time using this brief and the buyer's brand identity. No separate `build_creative` call is needed — the brief travels with the media buy.

For regulated categories (financial services, pharma), look for `supports_compliance: true` in the agent's creative capabilities. Compliance-aware agents validate required disclosures and regulatory elements during generation — include compliance requirements in the brief so the agent can enforce them.

## Previewing generative output

For generative formats, `preview_creative` serves two purposes:

**Before the campaign** — pass the brief manifest with `context_description` inputs to see representative samples of what the agent could generate:

```json theme={null}
{
  "request_type": "single",
  "quality": "draft",
  "creative_manifest": {
    "format_id": {
      "agent_url": "https://ads.seller-example.com",
      "id": "contextual_display_generative"
    },
    "assets": {
      "brief": {
        "content": "Highlight our sustainability story. Match tone to editorial context."
      }
    }
  },
  "inputs": [
    { "name": "Tech article", "context_description": "Article about semiconductor manufacturing" },
    { "name": "Lifestyle blog", "context_description": "Blog post about sustainable living" }
  ]
}
```

Use `quality: "draft"` for fast iteration on creative direction, `quality: "production"` for stakeholder review. These previews are illustrative — real output depends on live signals at serve time. Preview doesn't require an active media buy — you can preview before calling `create_media_buy`.

**After the campaign** — pass a `variant_id` from `get_creative_delivery` to replay exactly what was served:

```json theme={null}
{
  "request_type": "variant",
  "variant_id": "gen_tech_mobile_001"
}
```

The response includes the variant's actual manifest and a rendered preview. This is a faithful replay, not a re-generation.

See [Previewing generative creative](/docs/creative/task-reference/preview_creative#previewing-generative-creative) for the full mental model and expectations table.

## Delivery reporting

A sales agent implementing both protocols provides two complementary views of delivery data:

| Task                     | Protocol  | What it provides                                                                         |
| ------------------------ | --------- | ---------------------------------------------------------------------------------------- |
| `get_media_buy_delivery` | Media Buy | WHERE and HOW MUCH: impressions, spend, placement data, optional `by_creative` breakdown |
| `get_creative_delivery`  | Creative  | WHAT RAN and HOW: variant manifests, generation context, variant-level metrics           |

Both tasks are called on the same agent URL. Use `media_buy_id` and `creative_id` as join keys to correlate data across both responses.

For generative formats, `get_creative_delivery` is where the buyer sees what was actually generated. Each variant includes a manifest (the actual rendered creative — headline text, image URLs, format) and generation context (the signals that triggered generation, like page topic or device class). `get_media_buy_delivery` provides the aggregate view with spend, pacing, and dimensional breakdowns.

### Example: variant-level reporting on a sales agent

```json theme={null}
{
  "media_buy_id": "mb_12345",
  "currency": "USD",
  "reporting_period": {
    "start": "2026-03-01T00:00:00-05:00",
    "end": "2026-03-08T23:59:59-05:00",
    "timezone": "America/New_York"
  },
  "creatives": [
    {
      "creative_id": "brand_contextual_brief",
      "format_id": {
        "agent_url": "https://ads.seller-example.com",
        "id": "contextual_display_generative"
      },
      "totals": {
        "impressions": 300000,
        "spend": 15000,
        "clicks": 12000,
        "ctr": 0.04
      },
      "variant_count": 47,
      "variants": [
        {
          "variant_id": "gen_tech_mobile_001",
          "generation_context": {
            "context_type": "web_page",
            "topic": "technology, semiconductors",
            "device_class": "mobile"
          },
          "manifest": {
            "format_id": {
              "agent_url": "https://ads.seller-example.com",
              "id": "contextual_display_generative"
            },
            "assets": {
              "headline": {
                "asset_type": "text",
                "content": "Sustainable tech for a better tomorrow"
              },
              "hero_image": {
                "asset_type": "image",
                "url": "https://cdn.seller-example.com/generated/tech_mobile_001.jpg",
                "width": 300,
                "height": 250
              }
            }
          },
          "impressions": 45000,
          "spend": 2250,
          "clicks": 2700,
          "ctr": 0.06
        }
      ]
    }
  ]
}
```

## When to use a separate creative agent

A separate creative agent makes sense when:

* The creative service is **independent of any seller** — a creative management platform, ad server, or format conversion service
* Multiple sellers need to **serve the same creatives** — the buyer manages creatives in one place and distributes them
* The buyer wants **centralized creative analytics** across sellers

When the seller's ad product includes creative generation or management as an integrated capability, implementing both protocols on the sales agent is simpler for everyone.

## Capability discovery

Buyers check `get_adcp_capabilities` to understand what a sales agent supports:

```javascript theme={null}
const caps = await agent.getAdcpCapabilities({});

if (caps.errors) {
  throw new Error(`Capabilities check failed: ${caps.errors[0].message}`);
}

const sellsMedia = caps.supported_protocols.includes('media_buy');
const managesCreatives = caps.supported_protocols.includes('creative');
const acceptsInlineCreatives =
  caps.media_buy?.features?.inline_creative_management === true;

if (managesCreatives) {
  const { has_creative_library, supports_generation } = caps.creative;

  if (supports_generation) {
    // Agent generates creatives — look for generative formats
    const formats = await agent.listCreativeFormats({});
    if (formats.errors) {
      console.error('Format discovery failed:', formats.errors);
    }
  }

  if (has_creative_library) {
    // Agent hosts a library — can sync and browse creatives
    const creatives = await agent.listCreatives({
      account: { account_id: 'acc_123' }
    });
    if (creatives.errors) {
      console.error('Library browse failed:', creatives.errors);
    }
  }
}

if (sellsMedia && acceptsInlineCreatives && !managesCreatives) {
  // Inline-only seller: send package creatives on create_media_buy or update_media_buy.
}
```

## Related

* [Creative Specification](/docs/creative/specification) — Protocol requirements for creative agents
* [Implementing Creative Agents](/docs/creative/implementing-creative-agents) — Implementation guide for standalone creative agents
* [Generative Creative](/docs/creative/generative-creative) — Using `build_creative` for AI-powered generation
* [get\_creative\_delivery](/docs/creative/task-reference/get_creative_delivery) — Variant-level delivery reporting
* [get\_media\_buy\_delivery](/docs/media-buy/task-reference/get_media_buy_delivery) — Media buy delivery reporting
* [Media Buy Lifecycle](/docs/media-buy/media-buys/lifecycle) — State machine, sequenced flow, guaranteed deal IO path, creative sync timing
