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.
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/v3/creative/list-creative-formats-request.json
Response Schema: /schemas/v3/creative/list-creative-formats-response.json
Behavior by agent type
Any agent implementing the Creative Protocol can serve list_creative_formats. The response varies based on what the agent does:
Dedicated creative agents (like https://creative.adcontextprotocol.org):
- Return authoritative format definitions they own
- Provide full specifications for building and validating creatives
Sales agents implementing only Media Buy Protocol (like https://test-agent.adcontextprotocol.org):
- Return only formats used by active products
- Reference creative agents for authoritative format specifications
- Filter results based on whatβs actually purchasable
Sales agents implementing both protocols β return their own self-hosted format definitions alongside referenced formats. See Creative capabilities on sales agents.
See list_creative_formats (Sales Agent) for sales agent-specific behavior.
Request Parameters
| Parameter | Type | Required | Description |
|---|
format_ids | FormatID[] | No | Return only specific format IDs (from get_products response) |
type | string | No | (deprecated) Filter by type: audio, video, display, dooh. Prefer asset_types filter instead. |
asset_types | string[] | No | Filter to formats accepting these asset types: image, video, audio, text, html, javascript, url. Uses OR logic. Recommended over type filter. |
max_width | integer | No | Maximum width in pixels (inclusive) - matches if ANY render fits |
max_height | integer | No | Maximum height in pixels (inclusive) - matches if ANY render fits |
min_width | integer | No | Minimum width in pixels (inclusive) |
min_height | integer | No | Minimum height in pixels (inclusive) |
is_responsive | boolean | No | Filter for responsive formats (adapt to container size) |
name_search | string | No | Search formats by name (case-insensitive partial match) |
wcag_level | string | No | Filter to formats meeting at least this WCAG level: A, AA, AAA. See Accessibility. |
disclosure_positions | string[] | No | Filter to formats that support all of these disclosure positions. Matches against disclosure_capabilities when present, otherwise falls back to supported_disclosure_positions. |
disclosure_persistence | string[] | No | Filter to formats whose disclosure_capabilities include all of these persistence modes on at least one position. Values: continuous, initial, flexible. |
output_format_ids | FormatID[] | No | Filter to formats whose output_format_ids includes any of these. Returns formats that can produce these outputs β inspect their input_format_ids to see what inputs they accept. |
input_format_ids | FormatID[] | No | Filter to formats whose input_format_ids includes any of these. Returns formats that accept these creatives as input β inspect their output_format_ids to see what they can produce. |
pagination | object | No | Pagination: max_results (1-100, default 50) and cursor (opaque cursor from previous response) |
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
| Field | Description |
|---|
formats | Array of full format definitions (format_id, name, assets, renders). The type field is deprecated and may be omitted. |
creative_agents | Optional 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.
Catalog requirements
Formats declare catalog needs as catalog asset types in their assets array. This tells buyers which catalogs to sync before submitting creatives for that format.
{
"format_id": {
"agent_url": "https://creative.adcontextprotocol.org",
"id": "product_carousel_4x"
},
"name": "Product Carousel (4 items)",
"assets": [
{
"item_type": "individual",
"asset_id": "product_catalog",
"asset_type": "catalog",
"required": true,
"requirements": {
"catalog_type": "product",
"min_items": 4,
"required_fields": ["name", "price", "image_url"]
}
}
]
}
Catalog assets use asset_type: "catalog" with a requirements object containing:
| Field | Type | Description |
|---|
catalog_type | string | Required. The catalog type (e.g., product, store, job) |
min_items | integer | Minimum items the catalog must contain |
max_items | integer | Maximum items the format can render. Items beyond this limit are ignored |
required_fields | string[] | Fields that must be present on every item |
feed_formats | string[] | Accepted feed formats (e.g., google_merchant_center, linkedin_jobs) |
When catalog assets are present, buyers should sync the required catalogs via sync_catalogs before submitting creatives. See Catalogs for the full lifecycle.
Common Scenarios
import { testAgent } from '@adcp/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// 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.length} assets required`);
});
import { testAgent } from '@adcp/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// 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.forEach(asset => {
const label = asset.asset_role ?? asset.asset_id;
console.log(` - ${label}: ${asset.asset_type}`);
});
});
import { testAgent } from '@adcp/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// 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/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// 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`);
validated.formats.forEach(format => {
const assetTypes = format.assets.map(a => a.asset_type).join(', ');
console.log(`${format.name}: ${assetTypes}`);
});
Search by Name
import { testAgent } from '@adcp/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// 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})`);
});
import { testAgent } from '@adcp/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// 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`);
});
Discover Build Capabilities
Some formats declare the output formats they can produce via output_format_ids. A creative builder (like a multi-publisher template tool) may accept one asset group and produce many publisher-specific formats. A format transformer may accept an existing creative and reformat it.
The format schema expresses both sides of the relationship:
input_format_ids β existing creative formats this format accepts as input
output_format_ids β concrete output formats this format can produce
These filters are ANDed β a format must match all specified filters. Within each filter, matching is OR (any ID in the array matches). A bare format ID (no dimension parameters) matches all parameterized variants of that format; a parameterized ID is an exact match.
Note: asset_types and these filters target different things. A format that takes only creative manifests as input will have no entries in its assets array, so combining asset_types with input_format_ids will typically return no results.
Serve-time dynamic creative (DCO platforms that render from data feeds at ad serving time) is not expressed through these fields β those platforms describe their inputs via assets and their output via the format itself.
import { testAgent } from '@adcp/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// I need portrait video β what can generate it?
const result = await testAgent.listCreativeFormats({
output_format_ids: [
{ agent_url: 'https://creative.adcontextprotocol.org', id: 'video_9x16_15s' }
]
});
if (!result.success) {
throw new Error(`Request failed: ${result.error}`);
}
const validated = ListCreativeFormatsResponseSchema.parse(result.data);
validated.formats.forEach(format => {
const inputs = format.input_format_ids?.map(f => f.id) ?? ['(from brief)'];
console.log(`${format.name} accepts: ${inputs.join(', ')}`);
});
import { testAgent } from '@adcp/sdk/testing';
import { ListCreativeFormatsResponseSchema } from '@adcp/sdk';
// I have a landscape 16:9 video β what can I transform it into?
const result = await testAgent.listCreativeFormats({
input_format_ids: [
{ agent_url: 'https://creative.adcontextprotocol.org', id: 'video_16x9_30s' }
]
});
if (!result.success) {
throw new Error(`Request failed: ${result.error}`);
}
const validated = ListCreativeFormatsResponseSchema.parse(result.data);
validated.formats.forEach(format => {
const outputs = format.output_format_ids?.map(f => f.id) ?? [];
console.log(`${format.name} β ${outputs.join(', ')}`);
});
Each format includes:
| Field | Description |
|---|
format_id | Structured identifier with agent_url and id |
name | Human-readable format name |
type | (deprecated) Format type (audio, video, display, dooh). Use asset_types filter instead. |
assets | Array of all assets with required boolean indicating mandatory vs optional |
renders | Array of rendered output pieces (dimensions, role) |
input_format_ids | Creative formats this format accepts as input manifests (omitted for formats that work from raw assets) |
output_format_ids | Output formats this format can produce (omitted for formats that produce a single fixed output) |
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:
// Find formats requiring BOTH image AND text
const result = await agent.listCreativeFormats();
const imageAndText = result.formats.filter(format => {
const assetTypes = format.assets.map(a => a.asset_type);
return assetTypes.includes('image') && assetTypes.includes('text');
});
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:
// 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:
- Return authoritative formats - Include full specifications for formats you define
- Reference other agents - Use
creative_agents to delegate to other creative agents
- Include capabilities - Indicate what operations you support (validation, assembly, generation, preview)
- Support filtering - Implement filter parameters (type, asset_types, dimensions, etc.)
Error Handling
| Error Code | Description | Resolution |
|---|
REFERENCE_NOT_FOUND | Requested format_id doesnβt exist, or referenced creative agent is unavailable / not accessible. error.field MUST identify which typed parameter failed to resolve. | Verify format_id from get_products response; the format may be from a deprecated agent. |
INVALID_REQUEST | Invalid filter parameters | Check parameter types and values |
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:
- Build Creatives: Use
build_creative to assemble assets into format
- Preview: Use
preview_creative to see visual output
- Validate: Use
sync_creatives with dry_run: true
- Upload: Use
sync_creatives to upload to an agent-hosted creative library
Learn More