Skip to main content
Generate preview renderings of creative manifests. Supports both single creative preview and batch preview (5-10x faster for multiple creatives). Request Schema: /schemas/v3/creative/preview-creative-request.json Response Schema: /schemas/v3/creative/preview-creative-response.json

Quick Start

Single Creative Preview

{
  "request_type": "single",
  "creative_manifest": { /* includes format_id, assets */ }
}
Response:
{
  "response_type": "single",
  "previews": [
    {
      "preview_id": "prev_001",
      "renders": [
        {
          "render_id": "render_1",
          "output_format": "url",
          "preview_url": "https://creative-agent.example.com/preview/abc123",
          "role": "primary"
        }
      ],
      "input": { "name": "Default", "macros": {} }
    }
  ],
  "expires_at": "2027-02-15T18:00:00Z"
}
Embed the primary render in an iframe:
<iframe src="https://creative-agent.example.com/preview/abc123"
        width="600" height="400"></iframe>

Direct HTML Embedding

For faster rendering without iframe overhead, request HTML directly:
{
  "request_type": "single",
  "creative_manifest": { /* includes format_id, assets */ },
  "output_format": "html"
}
Response contains raw HTML:
{
  "response_type": "single",
  "previews": [
    {
      "preview_id": "prev_002",
      "renders": [
        {
          "render_id": "render_1",
          "output_format": "html",
          "preview_html": "<div class=\"creative\">...</div>",
          "role": "primary"
        }
      ],
      "input": { "name": "Default", "macros": {} }
    }
  ],
  "expires_at": "2027-02-15T18:00:00Z"
}
Only use output_format: "html" with trusted creative agents. Direct HTML embedding bypasses iframe sandboxing.

Batch Preview (Multiple Creatives)

Preview multiple creatives in one API call (5-10x faster):
{
  "request_type": "batch",
  "requests": [
    { "creative_manifest": { /* creative 1 */ } },
    { "creative_manifest": { /* creative 2 */ } }
  ]
}
Response contains results in order:
{
  "response_type": "batch",
  "results": [
    { "success": true, "creative_id": "creative_1", "response": { "previews": [...], "expires_at": "..." } },
    { "success": true, "creative_id": "creative_2", "response": { "previews": [...], "expires_at": "..." } }
  ]
}

Variant Preview (Post-Flight)

Preview what a specific variant looked like when served. Use variant_id from get_creative_delivery response:
{
  "request_type": "variant",
  "variant_id": "gen_mobile_morning"
}
Response:
{
  "response_type": "variant",
  "variant_id": "gen_mobile_morning",
  "previews": [
    {
      "preview_id": "prev_gen_morning",
      "renders": [
        {
          "render_id": "render_1",
          "output_format": "url",
          "preview_url": "https://creative-agent.example.com/preview/variant/gen_mobile_morning",
          "role": "primary",
          "dimensions": { "width": 300, "height": 250 }
        }
      ]
    }
  ],
  "manifest": {
    "format_id": {
      "agent_url": "https://creative.example.com",
      "id": "display_300x250_generative"
    },
    "assets": {
      "hero_image": {
        "asset_type": "image",
        "url": "https://cdn.creative.example.com/generated/mobile_morning_v1.jpg",
        "width": 300,
        "height": 250
      },
      "headline": {
        "asset_type": "text",
        "content": "Start Your Summer Right"
      }
    }
  },
  "expires_at": "2027-02-15T18:00:00Z"
}
Since each variant from get_creative_delivery includes its full manifest, you can also pass the manifest directly to preview_creative as a standard single request to re-render it.

Request Parameters

Variant Mode

ParameterTypeRequiredDescription
request_typestringYes"variant"
variant_idstringYesPlatform-assigned variant identifier from get_creative_delivery
creative_idstringNoCreative identifier for context
output_formatstringNo"url" (default) or "html"

Single Mode

ParameterTypeRequiredDescription
request_typestringYes"single"
format_idFormatIDNoFormat identifier (agent_url + id). Defaults to creative_manifest.format_id if omitted.
creative_manifestobjectYesComplete creative manifest with all required assets for the format.
inputsarrayNoArray of input sets for multiple preview variants
qualitystringNo"draft" (fast, lower-fidelity) or "production" (full quality). If omitted, the agent uses its own default.
output_formatstringNo"url" (default) or "html"
item_limitintegerNoMaximum catalog items to render per preview variant. Creative agents SHOULD default to a reasonable sample when omitted and the catalog is large.
template_idstringNoSpecific template ID for custom format rendering. Used when a format supports multiple visual templates.

Batch Mode

ParameterTypeRequiredDescription
request_typestringYes"batch"
requestsarrayYesArray of 1-50 preview requests
qualitystringNoDefault quality for all requests: "draft" or "production"
output_formatstringNoDefault output format for all requests
Each item in requests also accepts quality, output_format, item_limit, and template_id to override batch-level defaults for that individual preview.

Input Sets

Generate multiple preview variants by providing different contexts:
{
  "inputs": [
    { "name": "Desktop", "macros": { "DEVICE_TYPE": "desktop" } },
    { "name": "Mobile", "macros": { "DEVICE_TYPE": "mobile" } },
    { "name": "Morning Context", "context_description": "User commuting to work" }
  ]
}
Available macros: DEVICE_TYPE, COUNTRY, CITY, DMA, GDPR, US_PRIVACY, CONTENT_GENRE, etc. Context descriptions: For AI-generated content like host-read audio ads.

Response Format

Single Mode Response

{
  response_type: "single";
  previews: Preview[];       // One per input (or one default)
  interactive_url?: string;  // Optional sandbox for interactive formats
  expires_at: string;        // ISO 8601 expiration
}

Batch Mode Response

{
  response_type: "batch";
  results: Array<{
    success: boolean;
    creative_id: string;
    response?: { previews: Preview[]; expires_at: string; };
    errors?: Array<{ code: string; message: string; }>;
  }>;
}

Preview Structure

{
  preview_id: string;
  renders: Array<{
    render_id: string;
    output_format: "url" | "html" | "both";
    preview_url?: string;     // When output_format is "url" or "both"
    preview_html?: string;    // When output_format is "html" or "both"
    role: string;             // "primary", "companion", etc.
    dimensions?: { width: number; height: number; };
  }>;
  input: {
    name: string;
    macros?: Record<string, string>;
    context_description?: string;
  };
}
Multi-render formats: Some formats produce multiple pieces (video + companion banner). Each has its own render_id and role.

Previewing generative creative

For generative formats — contextual display, AI-generated native, conversational ads — the creative doesn’t exist until serve time. Preview serves two distinct purposes:

Pre-flight: representative samples

Before the campaign runs, use single or batch mode to preview what the agent could generate given different contexts. Pass inputs with context_description to simulate serve-time conditions:
{
  "$schema": "/schemas/creative/preview-creative-request.json",
  "request_type": "single",
  "quality": "draft",
  "creative_manifest": {
    "format_id": {
      "agent_url": "https://ads.seller-example.com",
      "id": "contextual_display_generative"
    },
    "assets": {
      "brief": {
        "content": "Highlight our sustainability story. Match tone to editorial context."
      }
    }
  },
  "inputs": [
    { "name": "Tech article", "context_description": "Article about semiconductor manufacturing" },
    { "name": "Lifestyle blog", "context_description": "Blog post about sustainable living" }
  ]
}
These previews are representative, not definitive. Real serve-time output depends on live signals (actual page content, user device, time of day) that can’t be fully simulated. Use draft quality for fast iteration on the brief and creative direction, then production quality for stakeholder review.

Post-flight: exact replay

After the campaign runs, use variant mode to see exactly what was served. Pass a variant_id from get_creative_delivery:
{
  "request_type": "variant",
  "variant_id": "gen_tech_mobile_001"
}
The response includes the variant’s actual manifest — the specific headline, image, and layout the agent generated for that context. This is a faithful replay, not a re-generation.

Setting expectations

AspectStandard creativeGenerative creative
Pre-flight previewExact — what you see is what runsRepresentative — shows the agent’s interpretation of the brief under simulated conditions
Post-flight previewSame as pre-flightExact — faithful replay of served output via variant mode
quality: "draft"Fast wireframe-quality renderFast, lower-fidelity generation for reviewing creative direction
quality: "production"Full-fidelity renderFull-quality generation for stakeholder sign-off
Number of variantsTypically 1 (or a few device variants)Potentially thousands — one per context
For generative formats where every impression produces a different creative (like AI chat or real-time contextual), pre-flight previews are best understood as samples from a distribution rather than the ad. The brief and brand identity constrain the distribution; previews let you verify the agent interprets those constraints correctly.

Conversational and interactive formats

For formats where the ad is stateful — AI chat, interactive experiences, conversational native — preview takes on additional meaning:
  • Pre-flight renders a representative first interaction or simulated conversation. The interactive_url field in the preview response (when present) provides a sandbox where reviewers can interact with the experience directly. Use context_description to simulate different conversation entry points.
  • Post-flight variant replay shows the actual exchange that occurred. For multi-turn formats, the variant manifest captures the full content the agent produced (message sequence, responses, media assets shown). The level of detail depends on the agent — some provide full transcripts, others provide summarized content with anonymized user signals.
These formats have the widest gap between pre-flight and post-flight: a pre-flight preview can only approximate one possible conversation path, while the live experience adapts to each user. Preview enough scenarios to verify tone, guardrails, and brand consistency.

Quality mismatch

If the requested quality level is not supported, the agent renders at the best quality it can provide. The protocol does not require agents to support both levels — an agent that only generates at one fidelity ignores the parameter. There is no response field echoing back the actual quality used, so if quality accuracy matters for your workflow, verify by visual inspection or ask the agent about its capabilities through list_creative_formats.

Preview expiration and variant retention

All previews have an expires_at timestamp. After expiration, preview URLs return errors and must be re-generated. For generative creative, re-generating a pre-flight preview may produce different output — the same brief and context can yield different creative each time. Variant previews (post-flight) depend on the agent retaining variant data. Agents are not required to retain variant data indefinitely. If you request a variant preview for a variant the agent has purged, expect a standard error response. For long-running campaigns, retrieve and archive variant previews periodically rather than assuming they will remain available.

Examples

Device Variants

{
  "$schema": "/schemas/creative/preview-creative-request.json",
  "request_type": "single",
  "creative_manifest": {
    "format_id": { "agent_url": "https://creative.adcontextprotocol.org", "id": "native_responsive" },
    "assets": {
      "hero_image": { "url": "https://cdn.example.com/hero.jpg", "width": 1200, "height": 627 },
      "headline": { "content": "Veterinarian Recommended" }
    }
  },
  "inputs": [
    { "name": "Desktop", "macros": { "DEVICE_TYPE": "desktop" } },
    { "name": "Mobile", "macros": { "DEVICE_TYPE": "mobile" } }
  ]
}

Batch with HTML Output

Preview multiple creatives for a grid layout:
{
  "request_type": "batch",
  "output_format": "html",
  "requests": [
    { "creative_manifest": { /* creative 1 */ } },
    { "creative_manifest": { /* creative 2 */ } }
  ]
}

AI-Generated Audio Preview

{
  "$schema": "/schemas/creative/preview-creative-request.json",
  "request_type": "single",
  "creative_manifest": {
    "format_id": { "agent_url": "https://creative.adcontextprotocol.org", "id": "audio_host_read_30s" },
    "assets": {
      "script_template": { "content": "This episode brought to you by {{BRAND_NAME}}..." },
      "brand_voice": { "content": "Friendly, enthusiastic, conversational." }
    }
  },
  "inputs": [
    { "name": "Weather Podcast", "context_description": "Podcast discussing weather patterns" },
    { "name": "Fitness Podcast", "context_description": "Podcast about marathon training" }
  ]
}

HTTP Status Codes

Single mode:
  • 200 OK - Preview generated successfully
  • 400 Bad Request - Invalid manifest or format_id
  • 404 Not Found - Format not supported
Batch mode:
  • 200 OK - Batch processed (check individual success fields)
  • 400 Bad Request - Invalid batch structure

Key Points

  • Every render’s preview_url returns an HTML page for iframe embedding
  • Use output_format: "html" for grids of 10+ previews (no iframe overhead)
  • Batch mode is 5-10x faster than individual requests
  • Preview URLs expire (check expires_at)
  • Handle partial batch failures by checking each result’s success field