> ## Documentation Index
> Fetch the complete documentation index at: https://docs.interchange.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Creative

> Manifest-based creative assets, nested under campaigns, with format coverage and per-product propagation

## Overview

A **Creative** in v2 is a **creative manifest** — a structured bundle containing uploaded assets (images, video, HTML, VAST tags), an optional brief, brand info auto-resolved from the campaign's advertiser, and a target ADCP format. Manifests are nested under campaigns and propagate to media buys at execution time.

<Note>
  **New in v2**: creatives are no longer stored at the advertiser level and referenced by campaigns. They are **created directly under a campaign** at `/api/v2/buyer/campaigns/:campaignId/creatives/...`. The model is also fully manifest-aligned with the [AdCP creative manifest spec](https://adcontextprotocol.org/schemas/latest/core/creative-manifest.json).
</Note>

<Note>
  **Field-name exception**: Creative manifests use **snake\_case** field names (`creative_id`, `campaign_id`, `format_id`, `template_id`, `brand_domain`, `target_format_ids`) because they are passed through verbatim to the ADCP wire-format. This is an intentional exception to v2's general camelCase convention — see the [migration guide](/v2/setup/migration-guide) for context.
</Note>

## Why this changed

V1 treated creatives as advertiser-level assets reused across campaigns. V2 tightens the model so:

* Each campaign sees exactly the formats its selected products require (`creativeFormats.required`)
* Asset uploads happen in a single multipart request with the manifest metadata
* Format and template auto-detection runs against the campaign's product mix
* Tracking macros and brand info are resolved from the campaign + advertiser context

The result is fewer mismatches between selected products and uploaded creatives, and a cleaner per-campaign creative library.

## Key fields

| Field               | Type   | Notes                                                                                                                                                                                                                                                                           |
| ------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `creative_id`       | string | Manifest ID                                                                                                                                                                                                                                                                     |
| `campaign_id`       | string | Owning campaign                                                                                                                                                                                                                                                                 |
| `name`              | string | Human-readable name                                                                                                                                                                                                                                                             |
| `message`           | string | Optional creative brief / direction text                                                                                                                                                                                                                                        |
| `template_id`       | string | Creative template (`display_image`, `display_html`, `video_standard`, vendor tags, etc.)                                                                                                                                                                                        |
| `format_id`         | object | `{ agent_url, id }` — **legacy** (v1 named-format) format reference. Mutually exclusive with `format_kind`.                                                                                                                                                                     |
| `format_kind`       | string | **Canonical** (AdCP 3.1) format selector — a bare enum (`image`, `video_vast`, `video_hosted`, …) with **no `agent_url`**. Video/audio duration rides in `params` (`duration_ms_exact` / `duration_ms_range`), not on `format_id`. See the [glossary](/v2/concepts/glossary#f). |
| `target_format_ids` | array  | Formats from campaign products this manifest can serve                                                                                                                                                                                                                          |
| `brand_domain`      | string | Auto-resolved from the campaign's advertiser                                                                                                                                                                                                                                    |
| `assets`            | array  | Uploaded assets (id, type, MIME, public URL, source)                                                                                                                                                                                                                            |
| `preview_url`       | string | URL to processed HTML preview hosted on GCS                                                                                                                                                                                                                                     |
| `tracking`          | object | Auto-generated impression and click tracker URLs                                                                                                                                                                                                                                |
| `sync_status`       | object | `{ synced, agent_count, last_synced_at }` across sales agents                                                                                                                                                                                                                   |
| `frequencyCaps`     | array  | Buyer-defined caps on this creative                                                                                                                                                                                                                                             |

## Asset types

V2 assets cover the full ADCP type spectrum:

| Type                                  | Purpose                                                           |
| ------------------------------------- | ----------------------------------------------------------------- |
| `IMAGE`                               | JPEG, PNG, GIF, WebP, SVG                                         |
| `VIDEO`                               | MP4, WebM, QuickTime                                              |
| `AUDIO`                               | MP3, WAV, OGG                                                     |
| `HTML`                                | Inline content or hosted URL                                      |
| `JAVASCRIPT` / `CSS`                  | Companion script and style assets                                 |
| `VAST`                                | VAST tag (URL or inline XML) — **renamed from v1's `VIDEO_VAST`** |
| `URL`                                 | Clickthrough, tracker pixel, or VAST URL with explicit `url_type` |
| `FONT` / `LOGO` / `DOCUMENT` / `TEXT` | Supporting assets                                                 |

URL assets are typed via `url_type`: `CLICKTHROUGH`, `TRACKER_PIXEL`, `TRACKER_SCRIPT`, or `VAST`. Webhook assets enable server-side dynamic content rendering (DCO) with HMAC or API-key signing.

## Lifecycle

<Steps>
  <Step title="Discover required formats">
    `GET /api/v2/buyer/campaigns/:campaignId/creatives/templates` returns available templates plus the selected products' required formats. V2-native declarations are returned in `campaign_format_options`; legacy format references remain in `campaign_format_ids` for compatibility. Each product's requirements are also broken out under `campaign_products`. The legacy named-format registry across agents is available at `GET /api/v2/buyer/formats`.
  </Step>

  <Step title="Create the manifest">
    POST a multipart request with files + JSON metadata. Scope3 auto-classifies assets, processes HTML to rewrite local references to CDN URLs, inserts ADCP macros, and generates a preview.
  </Step>

  <Step title="Validate coverage">
    `GET /api/v2/buyer/campaigns/:id` returns `creativeFormats: { required, covered, missing }`. Upload more manifests until `missing` is empty.
  </Step>

  <Step title="Propagate to media buys">
    On campaign execute, the manifests sync to each sales agent for the formats they support. A ready manifest is registered for delivery in the same transaction as its assets, so it cannot disappear between upload and assignment. Sync status is reflected in `sync_status` on each manifest.
  </Step>

  <Step title="Update or replace">
    `PUT` the manifest with new files, deletions, or reclassifications. Updates flow back to media buys.
  </Step>
</Steps>

## Media-buy compatibility results

When a media buy inherits creatives from its campaign, Scope3 checks each
creative against the selected products before delivery. An inherited creative
that cannot serve those products is omitted and reported in
`creative_compatibility_warnings` with a status of `incompatible` or
`unresolved` and a reason. Older creative records that do not contain a usable
format are reported in `legacy_creatives_excluded`.

Historical static-image labels such as `display_300x250`,
`banner_300x250`, and `display_300x250_nongenerative` can serve a product's
same-sized `display_300x250_image` placement without retyping the saved
creative. Scope3 sends the product's advertised format reference and still
checks the creative's asset type and dimensions before delivery. Other
legacy-format differences remain incompatible rather than being widened by
format family.

Scope3 preserves an imported legacy format label for traceability, but a saved
creative's canonical `format_kind` is authoritative for campaign and product
matching. New saved creatives must resolve a canonical kind. If an older
creative's assets, media type, dimensions, and import provenance do not identify
one format kind deterministically, Scope3 quarantines it for explicit upgrade
instead of guessing. Seller-specific format references are applied only when
the creative is adapted for that seller; they do not change the saved master.

If a create-media-buy request explicitly names an incompatible or unresolved
creative, the request is rejected instead of creating a buy that silently
drops it. Integrations should surface these response fields so a buyer can
replace or correct the creative before launch.

For creatives your integration creates, use the canonical `format_kind` field.
It never contains an agent URL. Scope3 only preserves a URL-bearing
`format_id` when an external third-party system explicitly supplied that
legacy reference.

## Conversational creative sessions

Creative sessions are the agent-native path for buyers who want to generate, compare, refine, validate, and save creatives without handling manifest details directly.

The intended user flow is:

1. **Idea** — the buyer describes the channel, audience, goal, and source assets.
2. **Draft gallery** — a creative adapter returns multiple draft variants for human review.
3. **Refine** — the buyer gives natural-language feedback like "make the book more prominent" or "less busy."
4. **Evaluate** — draft checks are advisory; final hard/blocking checks stop finalization.
5. **Finalize** — the approved leaf is saved as a campaign creative manifest.

Use `POST /api/v2/buyer/campaigns/:campaignId/creative-sessions` to start a session. The response is designed for MCPUI and includes the draft `variants[]`, `asset_store`, `renderer_capabilities`, `rendering_model`, staged evaluator badges, and `format_renders[]` once a final is approved.

<Note>
  Creative sessions are review workflows. They do not replace campaign creative manifests. Finalization is the transition point where a selected draft/refinement becomes a normal campaign creative with `creative_id`, `format_id`, assets, preview, and sync status.
</Note>

### Required placement shapes

When a campaign has required placements, a `format_renders[]` tile is produced per placement at its real size. A placement with an extreme aspect ratio — a wide leaderboard or a tall skyscraper — only renders at its true shape if the generator can compose that ratio natively. Gemini and FAL do; OpenAI generates a fixed set of shapes and crops to fit.

If your session's connected generator would crop such a placement and you have also connected a native-ratio generator (Gemini or FAL) for that advertiser, that one placement is rendered on the native-ratio generator instead — on your own connected key for it, billed to that vendor account, the same as any generation on that provider. Other placements in the session stay on your session generator. When no native-ratio generator is connected, the placement still renders on the session generator with an advisory note that it may crop; connect one to fix the shape.

## Asset lifecycle

Creative production uses three related but distinct asset layers:

| Layer              | What it is                                                                                                             | Stored as                                                                     | How to use it                                                                                                                                           |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Source asset**   | Buyer-supplied input such as a book cover, product photo, logo, DAM URL, catalog image, audio file, or reference image | `source_asset` and `asset_store.assets[]` inside the creative session         | Treat as raw input. Preserve locked assets exactly; track role, provenance, rights, checksum, dimensions, and render crop/mask metadata when available. |
| **Draft variant**  | A generated or composited creative direction for review                                                                | `variants[]` with preview URL, quality, status, lineage, and evaluator checks | Use for exploration. Drafts may be discarded, branched, or refined. They are not campaign creatives until finalized.                                    |
| **Final creative** | The approved execution saved to the campaign                                                                           | Creative manifest under `/campaigns/:campaignId/creatives`                    | Use for delivery. It carries the final render, linked assets, text assets, ADCP format ID, tracking, preview, and sync status.                          |

For locked product, package, logo, or book-cover assets:

* Set `locked_asset: true`, `can_transform: false`, `role: "product"` (or the closest role), and specific `preservation_notes`.
* Keep provenance separate from rights. `source: "upload"` or `source: "dam"` says where the asset came from; `rights.status` says whether it is cleared.
* `rights.status: "unknown"` is a non-blocking review warning for final approval. `restricted` or `expired` blocks finalization.
* If the source image includes studio background or whitespace, provide `render_crop`, `subject_bounds`, or a transparent cutout/mask when available. Cropping is a preservation-safe fallback; a real cutout produces cleaner final compositions.

## Seller-specific versions

The campaign's selected products determine which seller formats need coverage. Use the creative template/format endpoints before and after finalization:

1. `GET /api/v2/buyer/campaigns/:campaignId/creatives/templates` shows required campaign formats and available templates.
2. Start a creative session against the best matching creative adapter and target format.
3. Finalize the chosen direction into a creative manifest.
4. Re-check `creativeFormats` on `GET /api/v2/buyer/campaigns/:campaignId`.
5. If `creativeFormats.missing` still contains seller formats, generate or adapt seller-specific manifests for those formats.

Seller-specific versions should keep a common creative direction and source-asset lineage, but each saved manifest must match the actual seller format it covers. For example, the same "Wimbledon book hero" direction may need separate square image, portrait story, audio, video, or HTML executions depending on the selected products.

`format_renders[]` is the review surface for publisher/format previews. It helps a buyer inspect what the final creative looks or sounds like in a particular canonical renderer. The actual delivery object remains the saved creative manifest and its synced seller-specific format coverage.

## Performance loop

Creative work does not end at finalization. The full performance cycle is:

1. **Create or update campaign goals** — use `performanceConfig` on the campaign when optimizing toward events or metrics.
2. **Launch with format coverage** — execute only after required creative formats are covered.
3. **Collect delivery and outcome data** — use reporting plus conversion/measurement ingestion (`log_event`, measurement data sync, or measurement records depending on integration).
4. **Compare creative performance** — inspect performance by campaign, media buy, package, and creative where reporting dimensions are available.
5. **Iterate** — duplicate or start a new creative session from the winning direction, then refine the creative based on observed performance and seller feedback.

<Note>
  The Anjali/The Shift prototype exercises the creative build, preview, evaluator, and finalization loop. A complete performance cycle also needs live delivery, measurement ingestion, reporting by creative, and an optimization decision that feeds a new creative iteration.
</Note>

## Evaluator strategy

Creative evaluators answer different questions at different moments. Treat them as a selected set of checks, not a single score.

| Evaluator type | Question it answers                                                  | Typical stage |
| -------------- | -------------------------------------------------------------------- | ------------- |
| Core readiness | Is there a renderable preview and valid manifest structure?          | Draft, final  |
| Asset fidelity | Did locked assets stay intact, and are rights/provenance usable?     | Draft, final  |
| Brand/brief    | Does the direction fit the campaign brief and brand guidance?        | Draft, final  |
| Format/seller  | Does this execution satisfy the selected seller or publisher format? | Final         |
| Policy/safety  | Is there policy, claims, legal, or safety risk?                      | Final         |
| Performance    | Did it actually work after delivery?                                 | Postflight    |

Draft evaluator warnings should guide refinement. Final hard/blocking failures prevent finalization. Non-blocking final warnings, such as unknown source-asset rights, should be shown as review notes. Performance evaluators should only run after delivery/reporting data exists; pre-flight checks cannot prove a creative will win.

Longer term, evaluator selection should come from the creative session context:

* source assets and lock/rights metadata
* modality and renderer type
* campaign brief and brand guidance
* selected seller formats and publisher policies
* available adapter/seller evaluator capabilities
* postflight reporting and measurement data

## Common operations

### Create a creative manifest (multipart)

The endpoint accepts a `metadata` JSON field plus `files[]` form fields:

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.interchange.io/api/v2/buyer/campaigns/cmp_987654321/creatives/create \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: multipart/form-data" \
    -F 'metadata={
      "name": "Q2 hero video",
      "message": "30s product reveal — premium tone, 2-second hook",
      "template_id": "video_standard",
      "url_asset": { "url": "https://acme.com/promo", "url_type": "CLICKTHROUGH" },
      "assets": [
        { "filename": "hero-30s.mp4", "asset_type": "VIDEO", "label": "main_video" }
      ]
    };type=application/json' \
    -F "files=@hero-30s.mp4" \
    -F "files=@companion-banner.png"
  ```

  ```bash With a VAST tag theme={null}
  curl -X POST https://api.interchange.io/api/v2/buyer/campaigns/cmp_987654321/creatives/create \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: multipart/form-data" \
    -F 'metadata={
      "name": "VAST premium",
      "template_id": "video_vast",
      "url_asset": { "url": "https://ad.doubleclick.net/ddm/vast/...", "url_type": "VAST" }
    };type=application/json'
  ```
</CodeGroup>

<Note>
  Creative creation is a single multipart request: a JSON `metadata` field plus zero or more `files` parts (`-F "files=@..."`). The server accepts up to the configured `MAX_FILE_COUNT` files per request and pairs each file with the matching `assets[].filename` in the metadata.
</Note>

<Tip>
  File limits: 50 MB per file, 20 files per request. Allowed MIME types include images (JPEG, PNG, GIF, WebP, SVG, HEIC), video (MP4, WebM, QuickTime), audio (MP3, WAV, OGG), HTML/CSS/JS, fonts, PDF, and XML/markdown.
</Tip>

### List manifests

```bash theme={null}
curl "https://api.interchange.io/api/v2/buyer/campaigns/cmp_987654321/creativeManifest?take=50" \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
```

Filters: `search`, `includeFrequencyCaps`. Pagination: `take`, `skip`.

### Get / update / delete

```bash theme={null}
curl https://api.interchange.io/api/v2/buyer/campaigns/cmp_987654321/creatives/cm_abcdef \
  -H "Authorization: Bearer $SCOPE3_API_KEY"

curl -X PUT https://api.interchange.io/api/v2/buyer/campaigns/cmp_987654321/creatives/cm_abcdef \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -F 'metadata={
    "delete_asset_ids": ["asset_old"],
    "new_assets": [{ "filename": "v2.mp4", "asset_type": "VIDEO" }]
  };type=application/json' \
  -F "files=@v2.mp4"

curl -X DELETE https://api.interchange.io/api/v2/buyer/campaigns/cmp_987654321/creatives/cm_abcdef \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
```

### Render an ADCP preview

```bash theme={null}
curl -X POST https://api.interchange.io/api/v2/buyer/campaigns/cmp_987654321/creatives/cm_abcdef/preview \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
```

Calls the ADCP agent's `preview_creative` tool to render at native format dimensions. Useful for validation before publisher submission.

## Advertiser-scoped creative listing

`GET /api/v2/buyer/advertisers/:advertiserId/creatives` returns **all creatives scoped to the advertiser** — both promoted library creatives (`evergreen`/`reference` role) and flight-specific creatives attached to any campaign under this advertiser. A creative inherits the campaign's `advertiser_id` at creation time, so it appears in this list regardless of campaign attachment.

Use `?promoted=true` to filter to library creatives only (those explicitly saved with a role). Without this filter, the full set is returned — including creatives uploaded via the campaign-level creative dashboard that have not been promoted.

The advertiser creative listing also accepts `?search`, `?role`, `?source`, `?format_kind`, `?asset_type`, and `?dimensions` filters alongside standard `?take`/`?skip` pagination.

## Advertiser library: assign and unassign

Creatives can be saved to an advertiser library (promoted to `evergreen` or `reference` role) and then attached to campaigns via the advertiser-scoped endpoints:

| Method   | Path                                                                                  | Purpose                                                 |
| -------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `POST`   | `/api/v2/buyer/advertisers/:advertiserId/creatives/save-to-library`                   | Promote creatives to the advertiser library with a role |
| `POST`   | `/api/v2/buyer/advertisers/:advertiserId/creatives/:creativeId/campaigns`             | Assign a library creative to a campaign                 |
| `DELETE` | `/api/v2/buyer/advertisers/:advertiserId/creatives/:creativeId/campaigns/:campaignId` | Remove a library creative from a campaign               |

### Ownership validation

Both assign and unassign enforce advertiser ownership: the creative and the target campaign must belong to the same advertiser. If they belong to different advertisers, the endpoint returns **HTTP 422** with error code `INVALID_REQUEST`.

```json theme={null}
{
  "error": "Creative belongs to a different advertiser than the campaign.",
  "code": "INVALID_REQUEST",
  "field": "advertiserId"
}
```

A creative with no `advertiser_id` (not yet scoped to an advertiser) can be assigned to any campaign, and the backfill sets its `advertiser_id` to match the campaign's.

### Collection fan-out

When you assign a collection to a campaign, members whose `advertiser_id` conflicts with the campaign's advertiser are silently skipped. The response includes an `ownership_excluded` count so you can detect this. Check that all expected creatives appear in the campaign after a collection assign, and promote any skipped creatives to the correct advertiser before retrying.

## Format coverage on the campaign

When you `GET /api/v2/buyer/campaigns/:id`, the response includes:

```json theme={null}
"creativeFormats": {
  "required": [{ "format_kind": "video_hosted" }],
  "covered":  [{ "format_kind": "video_hosted" }],
  "missing":  []
}
```

`missing` is the prompt to upload more creatives. Coverage is computed against the formats every selected product needs.

## Tracking macros

When the format supports it, Scope3 auto-injects:

* An **impression tracker** URL as a `TRACKER_PIXEL` URL asset
* A **click tracker** URL that wraps the original clickthrough — the original is preserved in the `rurl` query parameter

ADCP universal macros (`{CAMPAIGN_ID}`, `{DEVICE_TYPE}`, `{COUNTRY}`, etc.) are filled at impression time. The `tracking.supported_macros` array on the manifest response lists which macros the format supports.

<Warning>
  Only one clickthrough URL per manifest. If multiple URL assets are flagged `url_type: CLICKTHROUGH`, manifest creation fails.
</Warning>

## Measurement endpoint and EU consent

The injected impression and click trackers fire to `ping.interchange.io` —
Scope3's own measurement domain in production (`/agentic/imp` for impressions,
`/agentic/clk` for clicks). Because it is Scope3's domain rather than a
registered third party, Google Ad Manager doesn't recognize it as a known
ad-tech vendor (see below). It powers impression counting, frequency capping,
emissions measurement, and conversion attribution.

### What the tracker carries

The impression URL carries identifiers and tokens — never raw PII:

| Param   | Meaning                                                                                                            |
| ------- | ------------------------------------------------------------------------------------------------------------------ |
| `dsid`  | Dataset ID — links the impression to the advertiser's conversion-attribution dataset                               |
| `cid`   | Creative ID                                                                                                        |
| `camp`  | Campaign ID                                                                                                        |
| `advid` | Advertiser ID                                                                                                      |
| `mb`    | Media buy ID, filled at serve time                                                                                 |
| `pkg`   | Package ID — left blank on synced creatives, which can map to multiple packages                                    |
| `axem`  | Emissions measurement token, filled at serve time                                                                  |
| `tmpx`  | HPKE-encrypted exposure token for frequency capping, filled at serve time (see [TMP](/v2/storefront/tmp/overview)) |
| `cb`    | Cachebuster                                                                                                        |

The click tracker carries the same identifiers and preserves the original
clickthrough in the `rurl` parameter.

<Note>
  `axem` and `tmpx` are filled by the **TMP Router** and are populated only when
  the publisher has connected [TMP](/v2/storefront/tmp/overview) — without it they
  resolve to empty, and the pixel still counts impressions but carries no
  emissions or frequency-cap signal.
</Note>

### Consent signals

Where the format or advertiser tracking config enables them, the tracker URL
includes consent macros as ad-server placeholders — `gdpr` (whether GDPR
applies), `gdpr_c` (the TCF consent string), and `us_p` (the US Privacy string).
The ad server fills them from the user's consent state at serve time and
forwards them to the endpoint. These are the only consent signals the pixel
carries today; there is no GPP (Global Privacy Platform) string.

### Clearing the Google Ad Manager "unknown ad technology" warning

When a creative is trafficked through Google Ad Manager, this clearing step is
the **publisher's** action (a GAM admin), not the buyer's. GAM scans the
creative for ad technology URLs and flags any domain it doesn't recognize on
Google's Ad Technology Providers list. Because `ping.interchange.io` is a Scope3
measurement domain, it surfaces under **Associated ad technology providers** as
an unknown URL with the note *"We found unknown URLs that may affect serving
eligibility."*

When the network has **Check reservation creatives for user consent** enabled,
an unrecognized domain blocks the creative from serving — including
non-personalized requests — in the EEA, the UK, and Switzerland; the Brazil
(LGPD) block applies regardless of that setting. The creative serves normally
everywhere else.

To clear it, the publisher adds `ping.interchange.io` as a custom ad partner URL
in the network's **EU user consent settings** (reachable from the **Go to
settings** link on the warning; the page requires specific GAM permissions, as
the warning notes). Selecting "No ad technology providers to declare" does *not*
clear a URL GAM has already detected in the creative.

## Format catalog

To inspect formats required by the campaign's selected products:

| Endpoint                                                      | Purpose                                                                                                                           |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `GET /api/v2/buyer/campaigns/:campaignId/creatives/templates` | List the deduplicated V2 `format_options`, legacy format IDs, per-product requirements, and available templates for the campaign. |
| `GET /api/v2/buyer/formats`                                   | Cross-agent legacy named-format registry (all legacy format IDs discovered from sales agents).                                    |
| `GET /api/v2/buyer/formats/:agentUrl/:formatId`               | Format details for a specific format on a specific agent.                                                                         |

## Propagation to media buys

At campaign execute, the manifest is synced to each sales agent that supports its `format_id`. The same manifest can serve multiple media buys; later updates re-sync. Use `sync_status` to confirm publishers have received the latest version.

### Creative transport modes

Interchange chooses the creative transport mode per sales agent:

* **Creative library sync** — sellers that advertise a creative library through `creative.has_creative_library: true` receive manifests through `sync_creatives`, and packages reference them with `creative_assignments`.
* **Inline creative delivery** — sellers that advertise `creative.has_creative_library: false` receive the creative manifest inline on each package that needs it.

For legacy or unknown capabilities (`creative.has_creative_library` is `null` or absent), Interchange falls back to the seller's advertised tools and uses `sync_creatives` when available.

If `sync_creatives` fails and the seller allows inline creatives, Interchange falls back to inline package delivery for that seller. If the seller is library-only and `sync_creatives` fails, the media-buy create or update request fails synchronously instead of silently continuing.

## Related concepts

<CardGroup cols={2}>
  <Card title="Campaign" href="/v2/object-guides/campaign" icon="rocket">
    Owning campaign — formats come from its products
  </Card>

  <Card title="Brand" href="/v2/object-guides/brand-story" icon="book-open">
    Brand info auto-resolved from the advertiser
  </Card>
</CardGroup>
