Skip to main content

Documentation Index

Fetch the complete documentation index at: https://agenticadvertisingorg-changeset-release-main.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Creative libraries let buyers manage creatives through AdCP — browsing existing assets, uploading new ones, assigning them to campaigns, and tracking approval status. A creative library is hosted by any agent that declares has_creative_library: true in its capabilities: ad servers (CM360, Flashtalking), creative management platforms (Celtra), or sales agents with inline creative management.

The model

A creative library organizes assets at three levels:
LevelAdCP equivalentExamples
AccountAccount (via accounts protocol)Advertiser in CM360, brand workspace in Celtra
Conceptconcept_id / concept_nameFlashtalking concept, CM360 creative group, Celtra campaign folder
CreativeCreative item with creative_id, format_id, assetsA 300x250 display ad, a 30s video spot
Concepts group related creatives across sizes and formats. A “Holiday 2026” concept might contain a 300x250 banner, a 728x90 leaderboard, and a 30s video — all expressing the same campaign idea. Use concept_id to filter and manage them as a group.

Creative state and assignment state are separate

Two things the library tracks independently:
  • Creative state — the review status of the creative itself: processing, pending_review, approved, rejected, or archived. Set by the creative agent’s review workflow. Applies to the creative as a library asset, regardless of where it is used.
  • Assignment state — the relationship between a creative and a package on a specific media buy. Created when the buyer assigns the creative (via sync_creatives, creative_assignments, or inline creatives on create_media_buy). Released when the media buy or package is rejected, canceled, or completed, or when the buyer removes the assignment.
These lifecycles are tracked independently:
  • A creative in the library has zero or more active assignments at any time.
  • Rejecting, canceling, or completing a media buy releases its assignments. It does not change the creative’s review state, remove the creative from the library, or affect the creative’s use in other media buys.
  • When a creative’s review state changes after assignments exist (e.g., a seller revokes an approval, or approves a previously rejected creative), sellers MAY continue or stop in-flight serving based on the new state. Buyers SHOULD re-fetch approval_status per package via get_media_buys after a creative-state change to detect assignment-level impact. See creative review.
Buyer agents reusing a library creative on a new media buy check creative state to know whether the asset is usable, and assignment state to know where it is currently in flight.

Creatives outlast campaigns

A creative MUST persist in the library independently of the buys that reference it. Buy rejection, cancellation, or completion releases assignments only — the creative remains in the library at its current status and may be reused on subsequent buys. This holds regardless of how the creative entered the library: explicit sync_creatives, inline creative on create_media_buy, or platform-native upload exposed through AdCP. Sellers whose underlying ad server has no library object distinct from per-buy attachment satisfy this rule by exposing the buyer-synced creative through list_creatives for the buy’s lifetime and continuing to expose its terminal state (including archived) after teardown — the library can be a thin view over per-buy storage; it does not need to be a separate store. Retention beyond active assignments is seller-defined. An agent MAY archive an unassigned creative due to inactivity, post-flight expiry, or storage policy (see creative status lifecycle), and MAY transition approvedrejected for policy revocation, takedown, or content drift. Whenever a creative’s state changes after it has been synced by a buyer, the seller MUST make the new state observable so the buyer can resync, replace, or stop relying on the asset before reuse:
  • For state changes affecting an active media buy (e.g., approvedrejected on a creative with live assignments), sellers MUST surface a corresponding impairment on the buy. See media buy health.
  • For state changes on creatives with no active assignments (e.g., seller archives an unassigned creative for inactivity), sellers MUST reflect the new status on the next list_creatives read — that snapshot is the conformant signal today, per the snapshot-and-log contract. A push channel for account-scoped creative state changes is being defined under the creative lifecycle webhooks RFC; when that channel ships, sellers SHOULD additionally fire on it.
Buyers SHOULD confirm availability via list_creatives before reuse on a new buy. A library creative is the bundle of inputs the buyer supplied — uploaded assets, a brief, brand and catalog pointers, or any combination. Retention applies to the bundle; whether the format’s rendered outputs are individually addressable is a format-level concern and is independent of library retention.

Connecting to a library

Establish account access before querying:
{
  "accounts": [{
    "account_id": "acct_acme_2026",
    "account_name": "Acme Corp",
    "credentials": {
      "api_key": "..."
    }
  }]
}
The account setup is the same whether the library is on a standalone creative agent or a sales agent. See accounts protocol for details.

Browsing creatives

Use list_creatives to browse the library. Filter by concept, format, status, tags, or date range:
{
  "filters": {
    "concept_ids": ["concept_holiday_2026"],
    "statuses": ["approved"],
    "format_ids": [{
      "agent_url": "https://ads.flashtalking-example.com",
      "id": "display_300x250"
    }]
  },
  "include": {
    "variables": true,
    "assignments": true
  }
}
Each creative in the response includes:
{
  "creative_id": "ft_88201",
  "name": "Holiday 2026 - Medium Rectangle",
  "format_id": {
    "agent_url": "https://ads.flashtalking-example.com",
    "id": "display_300x250"
  },
  "status": "approved",
  "concept_id": "concept_holiday_2026",
  "concept_name": "Holiday 2026 Campaign",
  "created_date": "2026-10-15T14:00:00Z",
  "updated_date": "2026-11-20T09:30:00Z",
  "tags": ["holiday_2026", "display"],
  "variables": [
    {
      "variable_id": "headline",
      "name": "Headline text",
      "type": "text",
      "default_value": "Holiday Sale — Up to 40% Off"
    }
  ],
  "assignments": [
    { "package_id": "pkg_premium_display", "weight": 100 }
  ]
}
The status field reflects the creative’s current state in the library: processing, pending_review, approved, rejected, or archived. See creative review for how status transitions work.

Uploading creatives

Use sync_creatives to upload new creatives or update existing ones. The operation uses upsert semantics — if a creative_id already exists, it updates; otherwise it creates.
{
  "creatives": [
    {
      "creative_id": "acme_video_001",
      "name": "Holiday Sale 30s",
      "format_id": {
        "agent_url": "https://creative.adcontextprotocol.org",
        "id": "video_standard_30s"
      },
      "assets": {
        "video": {
          "url": "https://cdn.acme-example.com/holiday-sale-30s.mp4",
          "width": 1920,
          "height": 1080,
          "duration_ms": 30000
        },
        "click_url": {
          "url": "https://acme-example.com/holiday-sale"
        }
      }
    }
  ]
}
The response tells you what happened to each creative:
{
  "creatives": [
    {
      "creative_id": "acme_video_001",
      "action": "created"
    }
  ]
}
After upload, the creative enters the library’s review process. Check list_creatives to see when it transitions from pending_review to approved.

Uploading with assignments

Assign creatives to packages in the same call:
{
  "creatives": [
    {
      "creative_id": "acme_video_001",
      "name": "Holiday Sale 30s",
      "format_id": { "agent_url": "...", "id": "video_standard_30s" },
      "assets": { "...": "..." }
    }
  ],
  "assignments": [
    {
      "creative_id": "acme_video_001",
      "package_id": "pkg_premium_video"
    }
  ]
}

Generating tags from library creatives

When you need a serving tag for a creative in the library, use build_creative with creative_id instead of a manifest:
{
  "creative_id": "ft_88201",
  "concept_id": "concept_holiday_2026",
  "target_format_id": {
    "agent_url": "https://ads.flashtalking-example.com",
    "id": "display_300x250"
  }
}
The creative agent resolves the creative_id from its library and returns a manifest with the serving tag. The tag format depends on the platform:
  • Flashtalking, Celtra: Universal tags that adapt to any environment. No placement context needed.
  • CM360: Placement-level tags that require trafficking context. Pass media_buy_id and package_id:
{
  "creative_id": "cm360_creative_12345",
  "target_format_id": {
    "agent_url": "https://ads.cm360-example.com",
    "id": "display_300x250"
  },
  "media_buy_id": "buy_holiday_q4",
  "package_id": "pkg_premium_display"
}
See tag generation models for the full breakdown.

Assigning creatives to campaigns

There are two paths for attaching library creatives to a media buy:

Path 1: Creative assignments on the package

Reference library creatives by ID when creating the media buy:
{
  "packages": [{
    "product_id": "premium_display",
    "creative_assignments": [
      { "creative_id": "ft_88201", "weight": 60 },
      { "creative_id": "ft_88202", "weight": 40 }
    ]
  }]
}
This works when the creative is already in the agent’s library (via sync_creatives or the platform’s own upload flow).

Path 2: Inline creatives on the package

Upload the creative directly with the media buy — no separate sync step:
{
  "packages": [{
    "product_id": "premium_display",
    "creatives": [{
      "creative_id": "acme_banner_001",
      "name": "Holiday banner",
      "format_id": { "agent_url": "...", "id": "display_300x250" },
      "assets": { "...": "..." }
    }]
  }]
}
The agent adds the creative to its library and assigns it to the package in one operation. See inline creative management for details. Inline creatives follow the same library lifecycle as sync_creatives uploads. The inline form is a convenience — “sync and assign in one call” — not a separate lifecycle. Once submitted, the creative enters the library with the same review flow, retention, and identifiers it would have under sync_creatives. If the create_media_buy task resolves as pending_manual and the buy never activates, or if the buy is rejected or canceled, only the package assignments are released; the creatives remain in the library and may be referenced by creative_id in a subsequent create_media_buy call. This assignment-release behavior is normative on the media-buy side — see the Media Buy State Transitions rule. Creative review proceeds independently of the media buy outcome. Sellers MUST NOT skip review solely because the buy did not activate, and a buy rejection does not by itself imply rejection of the submitted creatives — a creative rejection MUST be a deliberate review decision with its own rejection_reason, not implicit from the containing buy’s status. Sellers MAY deprioritize review of creatives that currently have no active assignments, provided review completes before any future assignment activates. Capability-flag scope. inline_creative_management: true advertises that the sales agent accepts inline creatives on create_media_buy; it does not tie the inline creative’s lifecycle to the buy. The decoupled library lifecycle applies regardless of submission path.

Multi-seller distribution

When you work with multiple sellers, build creatives once and distribute them:
  1. Build on your creative agent:
{
  "message": "Create a holiday promotion banner",
  "target_format_ids": [
    { "agent_url": "https://creative.adcontextprotocol.org", "id": "display_300x250" },
    { "agent_url": "https://creative.adcontextprotocol.org", "id": "display_728x90" }
  ]
}
  1. Sync to each seller’s library:
{
  "creatives": [
    {
      "creative_id": "holiday_2026_300x250",
      "name": "Holiday 2026 - Medium Rectangle",
      "concept_id": "concept_holiday_2026",
      "format_id": { "agent_url": "https://creative.adcontextprotocol.org", "id": "display_300x250" },
      "assets": { }
    }
  ]
}
Call sync_creatives on each sales agent separately. Use the same creative_id and concept_id across sellers so you can correlate the same creative and campaign concept across your media buys. See Multi-agent creative orchestration for the full pattern.
  1. Track approval per seller — each seller reviews independently. Poll list_creatives on each agent to check status. A creative may be approved on one seller and rejected on another based on their policies.

Tracking approval status

Creative approval operates at two levels: Library level: The status field on each creative in list_creativesprocessing, pending_review, approved, rejected, or archived. Package level: The approval_status on each creative in get_media_buyspending_review, approved, or rejected with rejection_reason. A creative can be approved in the library but rejected at the package level if it violates placement-specific policies. Poll both after syncing or submitting a media buy with new creatives.

Dynamic creative optimization (DCO)

Creatives with dynamic content variables appear in the library with a variables array when you request include: { variables: true }. Each variable defines a slot that the ad server fills at serve time:
{
  "variables": [
    {
      "variable_id": "headline",
      "name": "Headline text",
      "type": "text",
      "default_value": "Holiday Sale — Up to 40% Off"
    },
    {
      "variable_id": "product_image",
      "name": "Product image",
      "type": "image",
      "default_value": "https://cdn.acme-example.com/hero.jpg"
    },
    {
      "variable_id": "cta_color",
      "name": "CTA button color",
      "type": "color",
      "default_value": "#FF6600"
    }
  ]
}
Use has_variables: true in list_creatives filters to find DCO creatives. Variable types match common platform patterns: text, color, image, video, number, boolean. How the ad server uses these variables at serve time (data feeds, targeting rules, optimization algorithms) is outside AdCP’s scope. AdCP models the variable slots, not the optimization logic.

Next steps