> ## Documentation Index
> Fetch the complete documentation index at: https://agenticadvertisingorg-snap-format-preview-links.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Template Format IDs

> Template format IDs in AdCP let a single format definition support many dimension variants without creating separate formats for each size.

Template formats allow a single format definition to support multiple dimension or duration variants without creating separate format definitions for each variant. This eliminates format explosion when publishers support many similar variants.

## The Problem: Format Explosion

Without template formats, each dimension variant requires a separate format definition and format\_id:

```json theme={null}
{"format_id": {"agent_url": "...", "id": "display_300x250"}}
{"format_id": {"agent_url": "...", "id": "display_300x600"}}
{"format_id": {"agent_url": "...", "id": "display_728x90"}}
{"format_id": {"agent_url": "...", "id": "display_970x250"}}
// ... 50+ more sizes
```

**Publisher with 50 placement sizes** → 50 separate format definitions to create, maintain, and document.

## The Solution: Template Formats with Parameters

A single template format definition (`display_static`) accepts dimension fields in the format\_id object, allowing creatives to specify their exact dimensions.

## Format Types and Format IDs

There are **two types of format definitions**, which produce **three types of format IDs**:

### Format Definitions

1. **Concrete formats** - Fixed dimensions in format definition
   * Have `renders` array with explicit dimensions
   * Example: `display_300x250` always means 300×250px
   * Cannot accept parameters

2. **Template formats** - Accept parameters in format\_id
   * Have `accepts_parameters` array listing accepted parameters
   * Example: `display_static` can be any dimensions
   * Can be used with or without parameters

### Format IDs

1. **Concrete format\_id** - References a concrete format
   * Example: `{id: "display_300x250"}`
   * No parameters (none accepted)

2. **Template format\_id** - References a template format without parameters
   * Example: `{id: "display_static"}`
   * Used in placements to accept any dimensions

3. **Parameterized format\_id** - Template format with parameters
   * Example: `{id: "display_static", width: 300, height: 250}`
   * Used in creatives to specify exact dimensions (in pixels)

### Template Format Definition

Format definition that accepts parameters:

```json theme={null}
{
  "format_id": {
    "agent_url": "https://creative.adcontextprotocol.org"
    "id": "display_static"
  }
  "name": "Static Display Banner"
  "type": "display"
  "accepts_parameters": ["dimensions"]
  "renders": [
    {
      "role": "primary"
      "parameters_from_format_id": true
    }
  ]
  "assets": [
    {
      "item_type": "individual"
      "asset_id": "banner_image"
      "asset_type": "image"
      "required": true
      "requirements": {
        "parameters_from_format_id": true
      }
    }
    {
      "item_type": "individual"
      "asset_id": "clickthrough_url"
      "asset_type": "url"
      "required": true
    }
  ]
}
```

**Key fields:**

* `accepts_parameters: ["dimensions"]` - Format accepts dimensions (width/height in pixels) in format\_id
* `renders[].parameters_from_format_id: true` - Render parameters come from format\_id
* `requirements.parameters_from_format_id: true` - Asset parameters must match format\_id

### Parameterized Format ID (Creative Manifest)

Creative specifies exact dimensions in format\_id to use the template format:

```json theme={null}
{
  "format_id": {
    "agent_url": "https://creative.adcontextprotocol.org"
    "id": "display_static"
    "width": 300
    "height": 250
  }
  "assets": {
    "banner_image": {
      "asset_type": "image"
      "url": "https://cdn.example.com/banner-300x250.png"
      "width": 300
      "height": 250
    }
    "clickthrough_url": {
      "asset_type": "url"
      "url": "https://example.com/landing"
    }
  }
}
```

**This format\_id is parameterized:** Same dimensions always produce the same format\_id object, enabling deduplication and caching.

### Placement Constraints

**CRITICAL**: Sales agents MUST always return parameterized format\_ids (with specific dimensions/duration) in placements. Template format\_ids without parameters are ONLY used in format definitions from `list_creative_formats()`.

Publishers specify supported dimensions by listing all supported variants:

```json theme={null}
{
  "kind": "seller_inline",
  "placement_id": "homepage_banner",
  "name": "Homepage Banner",
  "mode": "targetable",
  "format_ids": [
    {
      "agent_url": "https://creative.adcontextprotocol.org",
      "id": "display_static",
      "width": 300,
      "height": 250
    },
    {
      "agent_url": "https://creative.adcontextprotocol.org",
      "id": "display_static",
      "width": 728,
      "height": 90
    }
  ]
}
```

**Validation:** Creative's format\_id must exactly match one of the placement's parameterized format\_ids.

**Why parameterized only in placements:**

* Buyers need to know exactly which dimensions are supported
* No ambiguity about what will be accepted
* Enables clear validation at creative submission time
* Template format\_ids without parameters are only for format discovery via `list_creative_formats()`

## Benefits

✅ **Scalability** - One template format supports unlimited dimension variants
✅ **Predictable** - Same dimensions = same format\_id (enables caching/deduplication)
✅ **Self-contained** - Creatives fully specify their format via format\_id
✅ **Portable** - A 300×250 creative works on any placement accepting 300×250
✅ **Publisher control** - Placements specify exact dimension constraints
✅ **Type-safe** - Width/height are numbers, not encoded strings
✅ **Backward compatible** - Concrete (non-template) formats work unchanged

## Format ID Fields

### Visual Formats (Display, DOOH, Native)

**Fields:**

* `width` (integer, minimum: 1) - Width in pixels
* `height` (integer, minimum: 1) - Height in pixels

**Example:**

```json theme={null}
{
  "agent_url": "https://creative.adcontextprotocol.org"
  "id": "display_static"
  "width": 300
  "height": 250
}
```

### Time-Based Formats (Video, Audio)

**Fields:**

* `duration_ms` (number, minimum: 1) - Duration in milliseconds

**Example:**

```json theme={null}
{
  "agent_url": "https://creative.adcontextprotocol.org"
  "id": "video_hosted"
  "duration_ms": 30000
}
```

### Combined (Video with Dimensions)

**Fields:**

* `width`, `height` (integers) - Video frame dimensions in pixels
* `duration_ms` (number) - Video length in milliseconds

**Example:**

```json theme={null}
{
  "agent_url": "https://creative.adcontextprotocol.org"
  "id": "video_hosted"
  "width": 1920
  "height": 1080
  "duration_ms": 30000
}
```

## Format Definition Patterns

### Display Format (Flexible Dimensions)

```json theme={null}
{
  "format_id": {
    "agent_url": "https://creative.adcontextprotocol.org"
    "id": "display_static"
  }
  "name": "Static Display Banner"
  "type": "display"
  "accepts_parameters": ["dimensions"]
  "renders": null
  "assets": [...]
}
```

### Video Format (Flexible Duration)

```json theme={null}
{
  "format_id": {
    "agent_url": "https://creative.adcontextprotocol.org"
    "id": "video_hosted"
  }
  "name": "Hosted Video"
  "type": "video"
  "accepts_parameters": ["duration"]
  "renders": null
  "assets": [...]
}
```

### DOOH Format (Pixel Dimensions)

```json theme={null}
{
  "format_id": {
    "agent_url": "https://creative.adcontextprotocol.org"
    "id": "dooh_static"
  }
  "name": "DOOH Static Display"
  "type": "dooh"
  "accepts_parameters": ["dimensions"]
  "renders": null
  "assets": [...]
}
```

**Creative with pixel dimensions:**

```json theme={null}
{
  "format_id": {
    "agent_url": "https://creative.adcontextprotocol.org"
    "id": "dooh_static"
    "width": 1920
    "height": 560
  }
  "assets": {...}
}
```

**Note**: All dimensions are in pixels. Physical screen dimensions (e.g., 48 feet × 14 feet billboard) are placement metadata, not format specifications.

### Generative Formats with Output Formats

Generative formats specify which output formats they can produce:

**Option 1: Generate specific dimensions**

```json theme={null}
{
  "format_id": {"agent_url": "...", "id": "display_generative"}
  "output_format_ids": [
    {"agent_url": "...", "id": "display_static", "width": 300, "height": 250}
    {"agent_url": "...", "id": "display_static", "width": 728, "height": 90}
  ]
}
```

**Option 2: Generate any dimension (template output)**

```json theme={null}
{
  "format_id": {"agent_url": "...", "id": "display_generative"}
  "output_format_ids": [
    {"agent_url": "...", "id": "display_static"}
  ]
}
```

Use template outputs when your generation logic can handle arbitrary dimensions. Buyer specifies dimensions when calling the generative format.

## Discovery Pattern

### Format Definitions: `list_creative_formats()`

Both creative and sales agents can return template format definitions via `list_creative_formats()`:

```json theme={null}
{
  "formats": [
    {
      "format_id": {"agent_url": "...", "id": "display_static"}
      "accepts_parameters": ["dimensions"]
      "assets": [...]
    }
  ]
}
```

**Purpose**: Buyers discover what format *types* are available and what parameters they accept.

### Placement Constraints: `get_products()`

**REQUIREMENT**: Sales agents MUST return parameterized format\_ids (with specific dimensions/duration) in placements. Template format\_ids without parameters are NOT allowed in placement specifications.

```json theme={null}
{
  "products": [{
    "placements": [{
      "kind": "seller_inline",
      "placement_id": "display_multi_size",
      "name": "Display multi-size",
      "mode": "targetable",
      "format_ids": [
        {"agent_url": "...", "id": "display_static", "width": 300, "height": 250},
        {"agent_url": "...", "id": "display_static", "width": 728, "height": 90}
      ]
    }]
  }]
}
```

**Purpose**: Buyers discover which *specific dimensions* are supported for each placement.

**Why parameterized format\_ids are required in placements:**

* Provides explicit list of accepted dimension variants
* Eliminates ambiguity about what will be accepted
* Enables clear validation at creative submission time
* Buyers can match their creative dimensions against specific placement requirements

**Discovery Flow**:

1. Buyer calls `list_creative_formats()` on creative or sales agent → learns `display_static` is a template format that accepts dimensions
2. Buyer calls `get_products()` on sales agent → learns which *specific dimensions* are supported (300×250, 728×90)
3. Buyer creates creative with parameterized format\_id matching one of the placement's supported dimensions

## Implementation Guidelines

### For Creative Agents

**Format definitions:**

* Set `accepts_parameters: ["dimensions"]` for formats with flexible dimensions
* Set `accepts_parameters: ["duration"]` for formats with flexible duration
* Set `accepts_parameters: ["dimensions", "duration"]` for formats with both (e.g., video with dimensions)
* Omit `renders` array when format accepts dimensions (dimensions come from format\_id)
* Include `renders` array for concrete formats with fixed dimensions

**Validation:**

* Validate format\_id dimensions against asset dimensions
* Ensure width/height/unit are present together (not partial)
* Return clear errors if format\_id doesn't match assets

**Format lookup/matching:**

* `list_creative_formats()` returns template formats (without dimension parameters)
* Format lookup by ID matches on base format (agent\_url + id), ignoring dimension parameters
* Example: Request for `{id: "display_static", width: 300, height: 250}` matches the template format `{id: "display_static"}`
* Dimension parameters are used for creative validation, not format discovery

### For Sales Agents

**Product responses - CRITICAL REQUIREMENT:**

* **MUST** always return parameterized format\_ids with specific dimensions/duration in placements
* **NEVER** return template format\_ids without parameters in placement `format_ids` arrays
* List all supported dimension/duration variants explicitly:
  ```json theme={null}
  {
    "placements": [{
      "kind": "seller_inline",
      "placement_id": "display_multi_size",
      "name": "Display multi-size",
      "mode": "targetable",
      "format_ids": [
        {"agent_url": "...", "id": "display_static", "width": 300, "height": 250},
        {"agent_url": "...", "id": "display_static", "width": 728, "height": 90},
        {"agent_url": "...", "id": "display_static", "width": 160, "height": 600}
      ]
    }]
  }
  ```

**Why this requirement exists:**

* Buyers need explicit lists of supported dimensions
* No ambiguity about what will be accepted
* Enables validation at creative submission time
* Template format\_ids without parameters are ONLY for `list_creative_formats()` responses

**Creative validation:**

* Ensure creative format\_id exactly matches at least one placement format\_id
* Match requires exact equality of all fields: agent\_url, id, width, height, duration\_ms
* No partial matches or "close enough" dimensions

### For Buyers

**Creative manifest construction:**

* Fetch format definitions to check `accepts_parameters` array
* Include dimension/duration fields in format\_id when using template formats
* Ensure asset dimensions match format\_id dimensions
* Validate against placement format\_ids before syncing

## Format ID Equality Rules

Two format\_ids are **identical** if and only if:

* `agent_url` matches exactly
* `id` matches exactly
* `width` matches exactly (if present)
* `height` matches exactly (if present)
* `duration_ms` matches exactly (if present)

### Canonicalization

When comparing format\_ids for equality or caching:

**Required fields:**

* Both `width` and `height` must be present together (cannot specify only one)
* All dimensions are in pixels (integers)

**Numeric precision:**

* Width and height are integers (300 not 300.5)
* Duration can be decimal (30000.5ms for fractional seconds)

**Field order:**

* JSON field order does NOT matter for equality
* `{"width": 300, "height": 250}` equals `{"height": 250, "width": 300}`

**Example equivalence:**

```json theme={null}
// These are IDENTICAL format IDs
{"agent_url": "...", "id": "display_static", "width": 300, "height": 250}
{"agent_url": "...", "id": "display_static", "width": 300, "height": 250}

// These are DIFFERENT format IDs
{"agent_url": "...", "id": "display_static", "width": 300, "height": 250}
{"agent_url": "...", "id": "display_static", "width": 728, "height": 90}

// INVALID - partial dimensions not allowed (schema validation will reject)
{"agent_url": "...", "id": "display_static", "width": 300}  // ❌ Missing height
```

## Matching Logic

### Placement Validation

**IMPORTANT**: Placements MUST always specify parameterized format\_ids with explicit dimensions/duration. Template format\_ids without parameters are NOT allowed in placements.

**Parameterized formats in placement (REQUIRED pattern):**

```json theme={null}
// Placement specifies exact supported dimensions
{"format_ids": [
  {"agent_url": "...", "id": "display_static", "width": 300, "height": 250},
  {"agent_url": "...", "id": "display_static", "width": 728, "height": 90}
]}

// Creative matches only if exact equality with one of the placement's format_ids
{"format_id": {"agent_url": "...", "id": "display_static", "width": 300, "height": 250}}  // ✅ Match
{"format_id": {"agent_url": "...", "id": "display_static", "width": 728, "height": 90}}   // ✅ Match
{"format_id": {"agent_url": "...", "id": "display_static", "width": 160, "height": 600}}  // ❌ Not in placement list
{"format_id": {"agent_url": "...", "id": "display_static"}}                               // ❌ Missing dimensions
```

## Migration from Concrete Formats

**Before (format explosion):**

```json theme={null}
// 50 separate format definitions
{
  "format_id": {"agent_url": "...", "id": "display_300x250"}
  "renders": [{"dimensions": {"width": 300, "height": 250}}]
}
{
  "format_id": {"agent_url": "...", "id": "display_728x90"}
  "renders": [{"dimensions": {"width": 728, "height": 90}}]
}
// ... 48 more
```

**After (single template format):**

```json theme={null}
{
  "format_id": {"agent_url": "...", "id": "display_static"}
  "accepts_parameters": ["dimensions"]
  "assets": [...]
}
```

**Creative manifest change:**

```json theme={null}
// Before: Format ID encoded dimensions in string
{
  "format_id": {"agent_url": "...", "id": "display_300x250"}
  "assets": {...}
}

// After: Dimensions as structured fields in format_id
{
  "format_id": {
    "agent_url": "..."
    "id": "display_static"
    "width": 300
    "height": 250
  }
  "assets": {...}
}
```

## Common Patterns

### IAB Standard Display Sizes

Instead of defining 15 separate formats for IAB sizes, use one template:

```json theme={null}
{
  "format_id": {"agent_url": "...", "id": "display_static"}
  "accepts_parameters": ["dimensions"]
}
```

Creatives specify their size via parameters:

* 300×250: `{id: "display_static", width: 300, height: 250}`
* 728×90: `{id: "display_static", width: 728, height: 90}`
* 160×600: `{id: "display_static", width: 160, height: 600}`
* etc.

### Video Duration Variants

Instead of separate 15s, 30s, 60s format definitions:

```json theme={null}
{
  "format_id": {"agent_url": "...", "id": "video_hosted"}
  "accepts_parameters": ["duration"]
}
```

Creatives specify duration: `{id: "video_hosted", duration_ms: 30000}`

### DOOH Screen Sizes

Instead of defining formats for every billboard size:

```json theme={null}
{
  "format_id": {"agent_url": "...", "id": "dooh_static"}
  "accepts_parameters": ["dimensions"]
}
```

Creatives specify pixel dimensions: `{id: "dooh_static", width: 1920, height: 560}`

**Note**: All dimensions are in pixels. Physical screen size (e.g., 48 feet × 14 feet) is placement metadata.

## See Also

* [Creative Manifests](/docs/creative/creative-manifests) - Complete manifest structure
* [Format Discovery](/docs/creative/formats) - How buyers discover formats
* [Placement Targeting](/docs/media-buy/creatives) - Assigning creatives to placements
* [Format References](/docs/protocol/format-references) - Normative contrast between `format_id` (pointer) and `format` (definition), including named validation errors
