Skip to main content

Migrating creatives

AdCP 3.0 makes three breaking changes to creative handling: the FormatCategory enum and format type field are removed, weighted creative assignments replace simple ID arrays, and a unified assets array replaces assets_required for format discovery.

Format category removal

What changed

v2 fieldv3 fieldChange type
type on format objects (FormatCategory enum)RemovedDeleted
format_types filter on list_creative_formats / get_productsRemovedDeleted

Why

The FormatCategory enum (video, display, audio, native, social, custom) was a coarse classifier that didn’t map well to multi-asset formats. A “video” format might also require display companion banners and text overlays. The enum forced implementors to pick one category for inherently multi-modal formats, which led to inconsistent filtering and discovery gaps.

Migration

Replace format_types filters with asset_types (what the format needs) or format_ids (exact match): v2:
{
  "format_types": ["video"]
}
v3 — filter by asset type:
{
  "asset_types": ["video"]
}
v3 — filter by exact format ID:
{
  "format_ids": [
    { "agent_url": "https://creatives.example.com", "id": "video_preroll_30s" }
  ]
}
asset_types returns any format that includes at least one asset of that type — so a video format with companion banners appears in both ["video"] and ["image"] results.

Creative assignments

What changed

v2 fieldv3 fieldChange type
creative_ids (string array)creative_assignments (object array)Replaced

Simple migration (equal weights)

v2:
{
  "creative_ids": ["creative_1", "creative_2"]
}
v3 — omit weight for equal distribution:
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/core/creative-assignment.json",
  "creative_id": "creative_1"
}
In context of a create_media_buy package:
{
  "creative_assignments": [
    { "creative_id": "creative_1" },
    { "creative_id": "creative_2" }
  ]
}
When weight is omitted on all assignments, impressions are distributed equally.

Weighted assignments

Control what percentage of impressions each creative receives:
{
  "creative_assignments": [
    { "creative_id": "hero_video", "weight": 60 },
    { "creative_id": "promo_video", "weight": 40 }
  ]
}
Weights are relative — they don’t need to sum to 100, but doing so makes intent clear.

Placement targeting

Assign specific creatives to specific placements within a product:
{
  "creative_assignments": [
    {
      "creative_id": "hero_video",
      "placement_ids": ["homepage_hero"],
      "weight": 100
    },
    {
      "creative_id": "sidebar_banner",
      "placement_ids": ["article_sidebar"],
      "weight": 100
    },
    {
      "creative_id": "fallback_banner",
      "weight": 50
    }
  ]
}
When placement_ids is omitted, the creative runs on all placements in the package. placement_ids references placement_id values from the product’s placements array.
sync_creatives does not support placement_ids. Use create_media_buy or update_media_buy for placement-level targeting.

Creative assignment schema

Each assignment object:
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/core/creative-assignment.json",
  "creative_id": "hero_video",
  "weight": 60,
  "placement_ids": ["homepage_hero"]
}
FieldTypeRequiredDescription
creative_idstringYesReferences a creative from list_creatives or sync_creatives
weightnumber (0-100)NoDelivery weight. Omit for equal distribution.
placement_idsstring[]NoTarget specific placements. Omit to run everywhere.

Asset discovery

What changed

v2 fieldv3 fieldChange type
assets_required (string array)assets (object array)Replaced
preview_imageformat_cardReplaced

Format assets

v2 — only listed required asset IDs:
{
  "format_id": { "agent_url": "https://creatives.example.com", "id": "display_300x250" },
  "name": "Standard Banner 300x250",
  "assets_required": ["main_image", "headline"]
}
v3 — lists ALL assets with required boolean:
{
  "format_id": { "agent_url": "https://creatives.example.com", "id": "display_300x250" },
  "name": "Standard Banner 300x250",
  "assets": [
    {
      "item_type": "individual",
      "asset_id": "main_image",
      "asset_type": "image",
      "required": true,
      "requirements": {
        "min_width": 300,
        "min_height": 250,
        "accepted_mime_types": ["image/png", "image/jpeg"]
      }
    },
    {
      "item_type": "individual",
      "asset_id": "headline",
      "asset_type": "text",
      "required": true,
      "requirements": {
        "max_length": 50
      }
    },
    {
      "item_type": "individual",
      "asset_id": "impression_tracker",
      "asset_type": "url",
      "required": false,
      "requirements": {
        "url_type": "tracking_pixel"
      }
    }
  ]
}

What the assets array provides

  • Full discovery — see ALL assets a format supports, not just required ones
  • Type information — each asset declares its asset_type (image, video, text, url, etc.)
  • Requirements — inline constraints (dimensions, length, MIME types)
  • Optional assets — trackers, companion banners, and other optional elements are now visible
  • Repeatable groups — carousel and multi-item formats use item_type: "repeatable_group"

Asset item types

Each entry in the assets array has an item_type discriminator: Individual assets (item_type: "individual"):
{
  "item_type": "individual",
  "asset_id": "main_video",
  "asset_type": "video",
  "required": true,
  "requirements": {
    "min_duration_seconds": 15,
    "max_duration_seconds": 30,
    "accepted_mime_types": ["video/mp4"]
  }
}
Repeatable groups (item_type: "repeatable_group") for carousels and multi-item formats:
{
  "item_type": "repeatable_group",
  "asset_group_id": "card",
  "required": true,
  "min_count": 2,
  "max_count": 10,
  "selection_mode": "sequential",
  "assets": [
    {
      "asset_id": "card_image",
      "asset_type": "image",
      "required": true,
      "requirements": {
        "min_width": 600,
        "min_height": 600,
        "aspect_ratio": "1:1"
      }
    },
    {
      "asset_id": "card_title",
      "asset_type": "text",
      "required": true,
      "requirements": {
        "max_length": 40
      }
    }
  ]
}

Format cards (replacing preview_image)

v2’s preview_image URL is replaced by format_card, which uses the creative rendering system:
{
  "format_card": {
    "format_id": {
      "agent_url": "https://creatives.example.com",
      "id": "format_card_standard"
    },
    "manifest": {
      "format_name": "Standard Banner 300x250",
      "preview_url": "https://cdn.example.com/previews/banner_300x250.png"
    }
  }
}

Migration steps

Format category

1

Remove format_types filters

Remove format_types from list_creative_formats and get_products requests.
2

Replace with asset_types

Use asset_types to filter formats by what assets they accept (e.g., ["video"], ["image"]).
3

Or use format_ids

Use format_ids for exact format matching when you know the specific formats you need.
4

Stop reading type field

Remove any code that reads the type field from format objects — it no longer exists in v3.

Creative assignments

1

Replace creative_ids

Replace creative_ids arrays with creative_assignments object arrays.
2

Set creative_id

Set creative_id on each assignment object.
3

Add weights

Add weights if you need non-equal distribution, otherwise omit weight.
4

Add placement_ids

Add placement_ids if you need placement-level targeting.
5

Update sync_creatives calls

These use creative_assignments too, but without placement_ids.

Asset discovery

1

Replace assets_required

Replace assets_required parsing with assets array iteration.
2

Check required boolean

Check required boolean on each asset instead of assuming all listed assets are required.
3

Use asset_type

Use asset_type to understand what kind of file each asset expects.
4

Handle item_type

Check for "individual" vs "repeatable_group".
5

Replace preview_image

Replace preview_image reads with format_card rendering.
6

Validate

Creative manifests must use exact asset_id values as keys.

Creative

Full creative documentation: formats, asset types, manifests, and creative agents.

Related: Channels | Pricing | Geo targeting | Catalogs | Attribution | AdCP 3.0 overview