Skip to main content

Format Support Declaration

Guide to declaring AdCP format support in OpenRTB 2.6 bid requests.

Overview

AdCP is an optional extension that publishers can choose to support for enhanced creative capabilities beyond standard OpenRTB formats. Publishers declare format support in bid requests to indicate which AdCP formats they can render.

Standard OpenRTB Format Support (Required)

The Imp object MUST include standard OpenRTB format fields:

  • banner: For display ad formats (with dimensions and format array)
  • native: For native ad formats (with native request object)

These standard fields are always required and form the baseline for ad serving.

Optional AdCP Format Declaration

Publishers MAY optionally declare AdCP format support in Imp.ext.aura.adcpFormats.

Critical Requirement: Publishers MUST fetch and cache format definitions during initialization before declaring format support in bid requests. Format definitions should NEVER be fetched during ad serving/rendering.

Request Structure

{
"imp": [
{
"id": "imp-1",
"native": { "request": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}}" },
{ "w": 728, "h": 90 }
]
},
"ext": {
"aura": {
"adcpFormats": [
{
"agent_url": "https://creative.adcontextprotocol.org",
"id": "display_300x250"
},
{
"agent_url": "https://creative.adcontextprotocol.org",
"id": "contextual_snippet_500char"
}
]
}
}
}
]
}

Format Reference Fields

FieldTypeRequiredDescription
adcpFormatsobject[]NoAdCP format IDs referencing standard or custom formats
adcpFormats[].agent_urlstringYesCreative agent URL
adcpFormats[].idstringYesFormat ID

Key Principles

1. Single Source of Truth

The format definition at the creative agent (agent_url) is the single source of truth for all format specifications. Publishers must respect the format definition exactly as provided by the creative agent.

2. Pre-Initialization Caching

Publishers must fetch and cache format definitions during initialization, not at render time:

// ✅ CORRECT: Fetch during initialization
async function initializeAdCP() {
const formats = [
{ agent_url: "https://creative.adcontextprotocol.org", id: "display_300x250" },
{ agent_url: "https://creative.adcontextprotocol.org", id: "contextual_weaving" }
];

for (const format of formats) {
const definition = await fetchFormatDefinition(format.agent_url, format.id);
formatCache.set(format.id, definition);
}
}

// ❌ WRONG: Never fetch during ad serving
async function renderAd(creative) {
// This will cause latency and performance issues
const definition = await fetchFormatDefinition(...); // DON'T DO THIS
}

3. Declare Only Cached Formats

Only declare formats in adcpFormats that have already been cached:

function buildBidRequest() {
const supportedFormats = []

// Only include formats we've successfully cached
for (const formatId of ['display_300x250', 'contextual_weaving']) {
if (formatCache.has(formatId)) {
supportedFormats.push({
agent_url: 'https://creative.adcontextprotocol.org',
id: formatId,
})
}
}

return {
imp: [
{
id: 'imp-1',
banner: { w: 300, h: 250 },
ext: {
aura: {
adcpFormats: supportedFormats,
},
},
},
],
}
}

Format Types

AdCP supports multiple format types, each identified by specific characteristics:

Format TypeDescriptionUse CaseIdentified By
contextual_weavingBrand context woven into LLM responseAI-native contextual advertisingtype: "contextual_weaving" + weaving_schema present
nativeNative ad formatTraditional native placementstype: "native"
displayDisplay bannerTraditional display placementstype: "display"
rich_mediaCustom HTML creativeRich media experiencestype: "rich_media"

Format Definition Structure

Format definitions retrieved from the creative agent specify:

{
"format_id": {
"agent_url": "https://creative.adcontextprotocol.org",
"id": "display_728x90"
},
"name": "Standard 728x90 Display Banner",
"type": "display",
"renders": [
{
"role": "primary",
"dimensions": {
"width": 728,
"height": 90,
"responsive": {
"width": false,
"height": false
},
"unit": "px"
}
}
],
"assets_required": [
{
"asset_id": "banner_image",
"asset_type": "image",
"asset_role": "hero_image",
"required": true,
"requirements": {
"width": 728,
"height": 90,
"acceptable_formats": ["jpg", "png", "gif"],
"max_file_size_kb": 150
}
},
{
"asset_id": "clickthrough_url",
"asset_type": "url",
"asset_role": "clickthrough",
"required": true
}
],
"supported_macros": [
"MEDIA_BUY_ID",
"CREATIVE_ID",
"CACHEBUSTER",
"DEVICE_TYPE",
"COUNTRY",
"DOMAIN"
]
}

Integration Levels

Publishers can choose their level of AdCP integration:

Level 1: Standard OpenRTB Only

{
"imp": [
{
"id": "imp-1",
"native": {
"request": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}}"
}
}
]
}

Capabilities:

  • Receive standard OpenRTB bids
  • Use adm field for creative markup
  • No AdCP features

Level 2: AdCP Display Formats

{
"imp": [
{
"id": "imp-1",
"native": {
"request": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}}"
},
"ext": {
"aura": {
"adcpFormats": [
{
"agent_url": "https://creative.adcontextprotocol.org",
"id": "display_300x250"
}
]
}
}
}
]
}

Capabilities:

  • Receive AdCP creative manifests
  • Validate creatives against format specs
  • Use universal macros
  • Fall back to adm if needed

Level 3: AI-Native Formats

{
"imp": [
{
"id": "imp-1",
"native": {
"request": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}}]}}"
},
"ext": {
"aura": {
"adcpFormats": [
{
"agent_url": "https://creative.adcontextprotocol.org",
"id": "contextual_weaving"
}
]
}
}
}
]
}

Capabilities:

  • All Level 2 features
  • Contextual weaving into LLM responses
  • AI-native advertising formats

Best Practices

1. Cache Format Definitions

Always cache format definitions during initialization:

const formatCache = new Map()

async function initializeFormats() {
const formats = await fetchSupportedFormats()

for (const format of formats) {
try {
const definition = await fetchFormatDefinition(
format.agent_url,
format.id
)
formatCache.set(format.id, definition)
console.log(`Cached format: ${format.id}`)
} catch (error) {
console.error(`Failed to cache format ${format.id}:`, error)
}
}
}

2. Handle Format Fetch Failures

Gracefully handle failures when fetching format definitions:

async function fetchFormatDefinition(agentUrl, formatId) {
try {
const response = await fetch(`${agentUrl}/formats/${formatId}`)
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
return await response.json()
} catch (error) {
console.error(`Failed to fetch format ${formatId}:`, error)
// Don't include this format in bid requests
return null
}
}

3. Validate Format Compatibility

Ensure your platform can render the format before declaring support:

function canRenderFormat(formatDefinition) {
// Check if we support the format type
if (!SUPPORTED_FORMAT_TYPES.includes(formatDefinition.type)) {
return false
}

// Check if we can handle required assets
for (const asset of formatDefinition.assets_required) {
if (asset.required && !canHandleAssetType(asset.asset_type)) {
return false
}
}

return true
}

4. Update Format Cache Periodically

Refresh format definitions periodically to get updates:

// Refresh every 24 hours
setInterval(
async () => {
await initializeFormats()
},
24 * 60 * 60 * 1000
)

Next Steps