Skip to main content
Discover creative formats supported by a creative agent. Returns full format specifications including asset requirements and technical constraints. Response Time: ~1 second (database lookup) Authentication: None required (public endpoint for format discovery) Request Schema: /schemas/v2/media-buy/list-creative-formats-request.json Response Schema: /schemas/v2/media-buy/list-creative-formats-response.json

Sales Agent vs Creative Agent Behavior

Both sales agents and creative agents implement list_creative_formats, but with different behaviors: Creative agents (like https://creative.adcontextprotocol.org):
  • Return authoritative format definitions they own
  • May reference other creative agents for additional formats
  • Provide full specifications for building and validating creatives
Sales agents (like https://test-agent.adcontextprotocol.org):
  • Return only formats used by active products
  • Reference creative agents for format specifications
  • Filter results based on what’s actually purchasable
See list_creative_formats (Sales Agent) for sales agent-specific behavior.

Request Parameters

ParameterTypeRequiredDescription
format_idsFormatID[]NoReturn only specific format IDs (from get_products response)
typestringNoFilter by type: audio, video, display, dooh
asset_typesstring[]NoFilter to formats accepting these asset types: image, video, audio, text, html, javascript, url. Uses OR logic.
max_widthintegerNoMaximum width in pixels (inclusive) - matches if ANY render fits
max_heightintegerNoMaximum height in pixels (inclusive) - matches if ANY render fits
min_widthintegerNoMinimum width in pixels (inclusive)
min_heightintegerNoMinimum height in pixels (inclusive)
is_responsivebooleanNoFilter for responsive formats (adapt to container size)
name_searchstringNoSearch formats by name (case-insensitive partial match)

Multi-Render Dimension Filtering

Formats may produce multiple rendered pieces (e.g., video + companion banner). Dimension filters use “any render fits” logic:
  • max_width: 300, max_height: 250 - Returns formats where AT LEAST ONE render is ≤ 300×250
  • Use case: “Find formats that can render into my 300×250 ad slot”
  • Example: Format with primary video (1920×1080) + companion banner (300×250) matches because companion fits

Response

FieldDescription
formatsArray of full format definitions (format_id, name, type, requirements, assets_required, renders)
creative_agentsOptional array of other creative agents providing additional formats
See Format schema for complete format object structure.

Recursive Discovery

Creative agents may reference other creative agents that provide additional formats:
{
  "creative_agents": [{
    "agent_url": "https://creative.adcontextprotocol.org",
    "agent_name": "AdCP Reference Creative Agent",
    "capabilities": ["validation", "assembly", "preview"]
  }]
}
Buyers can recursively query creative_agents. Track visited URLs to avoid infinite loops.

Common Scenarios

Get Specs for Product Format IDs

import { testAgent } from '@adcp/client/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/client';

// Get full specs for formats returned by get_products
const result = await testAgent.listCreativeFormats({
  format_ids: [
    {
      agent_url: 'https://creative.adcontextprotocol.org',
      id: 'video_15s_hosted'
    },
    {
      agent_url: 'https://creative.adcontextprotocol.org',
      id: 'display_300x250'
    }
  ]
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

// Validate response against schema
const validated = ListCreativeFormatsResponseSchema.parse(result.data);
validated.formats.forEach(format => {
  console.log(`${format.name}: ${format.assets_required.length} assets required`);
});

Find Formats by Asset Types

import { testAgent } from '@adcp/client/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/client';

// Find formats that accept images and text
const result = await testAgent.listCreativeFormats({
  asset_types: ['image', 'text']
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = ListCreativeFormatsResponseSchema.parse(result.data);
console.log(`Found ${validated.formats.length} formats`);

// Examine asset requirements
validated.formats.forEach(format => {
  console.log(`\n${format.name}:`);
  format.assets_required.forEach(asset => {
    console.log(`  - ${asset.asset_role}: ${asset.asset_type}`);
  });
});

Find Third-Party Tag Formats

import { testAgent } from '@adcp/client/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/client';

// Find formats that accept JavaScript or HTML tags
const result = await testAgent.listCreativeFormats({
  asset_types: ['javascript', 'html'],
  max_width: 970,
  max_height: 250
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = ListCreativeFormatsResponseSchema.parse(result.data);
console.log(`Found ${validated.formats.length} third-party tag formats ≤ 970×250`);

validated.formats.forEach(format => {
  const renders = format.renders || [];
  if (renders.length > 0) {
    const dims = renders[0].dimensions;
    console.log(`${format.name}: ${dims.width}×${dims.height}`);
  }
});

Filter by Type and Dimensions

import { testAgent } from '@adcp/client/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/client';

// Find video formats
const result = await testAgent.listCreativeFormats({
  type: 'video'
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = ListCreativeFormatsResponseSchema.parse(result.data);
console.log(`Found ${validated.formats.length} video formats`);

// Group by duration
const byDuration = {};
validated.formats.forEach(format => {
  const duration = format.requirements?.duration || 'unknown';
  if (!byDuration[duration]) byDuration[duration] = [];
  byDuration[duration].push(format.name);
});

Object.entries(byDuration).forEach(([duration, formats]) => {
  console.log(`${duration}s: ${formats.join(', ')}`);
});

Search by Name

import { testAgent } from '@adcp/client/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/client';

// Find mobile-optimized formats
const result = await testAgent.listCreativeFormats({
  name_search: 'mobile'
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = ListCreativeFormatsResponseSchema.parse(result.data);
console.log(`Found ${validated.formats.length} mobile formats`);

validated.formats.forEach(format => {
  console.log(`- ${format.name} (${format.type})`);
});

Responsive Formats

import { testAgent } from '@adcp/client/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/client';

// Find formats that adapt to container size
const result = await testAgent.listCreativeFormats({
  is_responsive: true,
  type: 'display'
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = ListCreativeFormatsResponseSchema.parse(result.data);
console.log(`Found ${validated.formats.length} responsive display formats`);

validated.formats.forEach(format => {
  console.log(`${format.name}: Adapts to container`);
});

Format Structure

Each format includes:
FieldDescription
format_idStructured identifier with agent_url and id
nameHuman-readable format name
typeFormat type (audio, video, display, dooh)
requirementsTechnical requirements (duration, file types, bitrate, etc.)
assets_requiredArray of required assets with specifications
rendersArray of rendered output pieces (dimensions, role)

Asset Roles

Common asset roles help identify asset purposes:
  • hero_image - Primary visual
  • hero_video - Primary video content
  • logo - Brand logo
  • headline - Primary text
  • body_text - Secondary text
  • call_to_action - CTA button text

Asset Types Filter Logic

The asset_types parameter uses OR logic - formats matching ANY specified asset type are returned. Example: asset_types: ['html', 'javascript', 'image']
  • Returns formats accepting html OR javascript OR image
  • Use case: “Show me formats I can use with any of my available asset types”
To find formats requiring specific combinations, filter results after retrieval:
test=false
// Find formats requiring BOTH image AND text
const result = await agent.listCreativeFormats();
const imageAndText = result.formats.filter(format => {
  const assetTypes = format.assets_required.map(a => a.asset_type);
  return assetTypes.includes('image') && assetTypes.includes('text');
});

Dimension Filtering for Multi-Render Formats

Some formats produce multiple rendered pieces:
  • Video with companion banner - Primary video (1920×1080) + banner (300×250)
  • Adaptive displays - Desktop (728×90) + mobile (320×50)
  • DOOH installations - Multiple screens with different dimensions
Dimension filters match if at least one render fits:
test=false
// Find formats with ANY render ≤ 300×250
const result = await agent.listCreativeFormats({
  max_width: 300,
  max_height: 250
});

// Returns formats where at least one render fits 300×250 slot
// May also include larger companion pieces

Implementation Requirements

When implementing list_creative_formats for a creative agent:
  1. Return authoritative formats - Include full specifications for formats you define
  2. Reference other agents - Use creative_agents to delegate to other creative agents
  3. Include capabilities - Indicate what operations you support (validation, assembly, generation, preview)
  4. Support filtering - Implement filter parameters (type, asset_types, dimensions, etc.)

Error Handling

Error CodeDescriptionResolution
FORMAT_NOT_FOUNDRequested format_id doesn’t existVerify format_id from get_products response
INVALID_REQUESTInvalid filter parametersCheck parameter types and values
AGENT_NOT_FOUNDReferenced creative agent unavailableFormat may be from deprecated agent

Best Practices

1. Use format_ids Parameter Most efficient way to get specs for formats returned by get_products. 2. Cache Format Specifications Format specs rarely change - cache by format_id to reduce API calls. 3. Filter by Asset Types for Third-Party Tags Search for asset_types: ['html'] or ['javascript'] to find tag-accepting formats. 4. Consider Multi-Render Formats Check renders array length - some formats produce multiple pieces requiring multiple placements. 5. Validate Asset Requirements Ensure your creative assets match format specifications before building creatives.

Next Steps

After discovering formats:
  1. Build Creatives: Use build_creative to assemble assets into format
  2. Preview: Use preview_creative to see visual output
  3. Validate: Use sync_creatives with dry_run: true
  4. Upload: Use sync_creatives to upload to media buy

Learn More