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
| Field | Type | Required | Description |
|---|---|---|---|
adcpFormats | object[] | No | AdCP format IDs referencing standard or custom formats |
adcpFormats[].agent_url | string | Yes | Creative agent URL |
adcpFormats[].id | string | Yes | Format 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 Type | Description | Use Case | Identified By |
|---|---|---|---|
contextual_weaving | Brand context woven into LLM response | AI-native contextual advertising | type: "contextual_weaving" + weaving_schema present |
native | Native ad format | Traditional native placements | type: "native" |
display | Display banner | Traditional display placements | type: "display" |
rich_media | Custom HTML creative | Rich media experiences | type: "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
admfield 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
admif 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
- Creative Manifests - Understanding creative manifest structure
- Tracking - Tracking implementation
- Contextual Weaving Format - AI-native format details