Safe preview grids
Both HTML and URL output contain untrusted content. Use the empty-sandbox and caller-controlled CSP pattern for every preview, including previews from publisher-designated providers. HTML output still requires an iframe; a grid or a trusted transport does not permit host-DOM insertion. Shadow DOM provides CSS isolation, not a security boundary. This illustrative React component uses thepreviewSrcdoc helper from that pattern. The application supplies schema-validated HTML renders; URL renders require an enforceable policy for the cross-origin document, or a new request for HTML output. The JSX examples use application-provided clients, manifests, and review callbacks and are not standalone scripts.
test=false
allow-scripts or allow-same-origin. Keep review controls in the host application. interactive_url does not authorize relaxing the preview policy; a separate interactive-testing integration needs its own isolation and credential controls.
Format showcase pages
Select only advertised preview capabilities and pass their explicit route IDs. These samples describe a renderer’s output, not creative approval or publisher acceptance. This application example assumescreateExampleManifest builds the required assets for each declaration.
test=false
response.previews[].renders[] with PreviewFrame. Show each failed item’s errors[] as text instead of accessing a nonexistent success response. Split larger catalogs into batches of at most 50.
Campaign review grids
Request production quality explicitly, retainquality_used, and check each item before enabling a production-fidelity review action. This illustrative component assumes the application has already selected the applicable endpoint and route and retained the publisher delegation separately.
test=false
productionFidelity checks the response’s quality claim only. The component uses previewEntryIsFresh from the cache example below both when rendering controls and when handling a click. Check expiry again when recording a review decision; an open review page does not extend the artifact’s lifetime. Reviewers still verify that the displayed render is complete under the caller’s policy and inspect rendering origin and applicable publisher delegation. Neither this button nor a production-quality response grants seller approval or authorization to serve. Cache entries below retain the request, complete result, and discovery provenance for those checks.
Choosing output format
Use URL output when the caller can enforce restrictive CSP on the cross-origin preview document as well as an empty sandbox. A host page’sframe-src directive restricts frame locations, not the child document’s subresources. Do not assume a provider’s embedding recommendations enforce caller policy.
Use HTML output when the caller constructs a srcdoc document with its own policy before provider markup. It is useful for grids and avoids a separate preview-page fetch, but still requires iframe isolation. Apply the same rules to server-rendered pages; do not interpolate preview markup into their HTML. Both paths may need a self-contained static rendering when scripts or remote media are blocked.
Caching review artifacts
A manifest-only key cannot identify a preview. The key must distinguish the endpoint and authenticated principal, exact renderer route, effective quality/output/template/catalog limit, all context and macro inputs, and the source/rendering/authority snapshots. Preserve the complete successful batch item, including its top-levelquality_used; saving only result.response drops that evidence.
The following executable helper defines application-local cache data, not new AdCP fields or SDK methods. The caller provides an existing client.preview_creative transport and schema-valid batch items. context records the exact endpoint and a non-secret tenant/principal scope matching that client, plus retained discovery evidence. sourceSnapshot binds the resolved source assets and any catalog/brand dependencies; renderingSnapshot identifies the known rendering configuration; authoritySnapshot records the applicable publisher delegation/presentation or an explicit undelegated state. These are local evidence identifiers, not self-granted authority. Do not put access tokens into keys.
If any snapshot is unknown, the helper bypasses the cache. A mutable URL, creative ID, source revision, or manifest hash alone is insufficient. Invalidate on an observed renderer, source, or delegation change; an omitted preview expiry does not freeze those dependencies. This example requires an explicit route and quality so server defaults cannot silently change the cache identity. Batch defaults are materialized onto each item before the request and key are created.
test=true
quality_used. Keep it attached to the original requested quality; do not label it production or place it in a different request’s cache slot. Renderer metadata, output URLs and expiry, echoed inputs, and local discovery provenance survive cache hits unchanged. A cached generative preview reuses the same sample; bypass the cache to request a new sample. Cache lookup does not approve the artifact or establish historical delivery. On terminal transport errors, use the transport’s existing error handling; the example keeps allow_async at its default false.
Preview URL Storage
Preview URLs are review resources, not just transport conveniences. A buyer, browser, or MCPUI host may fetch apreview_url after the original preview_creative call returns, after a pod restart, or from a different pod than the one that created the render.
For production agents, persist enough preview state to resolve every preview_url through its advertised lifetime:
- If
expires_atis present, keep the render available until that timestamp. - If
expires_atis omitted, treat the URL as non-expiring at the protocol layer and keep it available until explicit out-of-band revocation or purge. - Use shared storage for multi-process or multi-pod deployments: database metadata plus object storage, a shared cache tier, or an authenticated preview route that can recover the render from durable session state.
- Limit process-local
Mapor LRU storage to single-process demos, local development, or URLs whose advertised lifetime is shorter than the process lifetime you can actually guarantee.
Error handling
Check the batch envelope before reading item data, and check each item’ssuccess before reading response. Batch failures use errors[], not a singular error. This illustrative application code assumes a connected client and prepared requests.
test=false
Migration from Single to Batch
Before (Sequential):Use Case Patterns
Device Variants
Geographic Variants
Privacy Compliance Testing
AI Content Variants
Implementation Notes
For Creative Agents
Required:- Return complete HTML pages from
preview_url - Render every preview format the endpoint advertises, within the caller’s isolation policy
- Echo input parameters in response
- Validate manifest before rendering
- Apply macro values (or use defaults)
- Back preview URLs with storage that survives load balancing and restarts for the URL’s advertised lifetime
- Produce content compatible with the caller’s empty sandbox and restrictive CSP; do not ask consumers to enable scripts or same-origin access
- Set reasonable expiration (24-48 hours) for previews that should not be retained indefinitely
- Include render dimensions and
rendereraudit metadata when available - Provide
embeddingmetadata (sandbox policy, CSP) - Support responsive design
- Include accessibility features
For Buyers
- Render only in an empty-sandbox iframe with caller-enforced CSP; use the HTML
srcdocpath when URL policy cannot be enforced - Use
inputsarray for specific scenarios - Check
inputfield to confirm macros applied - Share review artifacts with their quality, rendering origin, delegation provenance, and expiry
- Treat
interactive_urlas a separate untrusted testing surface; it never grants preview sandbox permissions
For Publishers
- Return consistent HTML from preview URLs
- Implement responsive preview pages
- For legacy named formats, document the coarse universal set via
supported_macros; for canonical delivery paths, publish exactmacro_resolution_capabilitieson the selected format option - Clarify preview vs production differences
- Consider providing
interactive_urlfor testing
Related Documentation
- preview_creative - Basic usage and parameters
- Creative Manifests - Manifest structure
- Universal Macros - Available macro values