> ## 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.

# Create advertiser creative master

> Create a creative manifest under an advertiser, before any campaign exists

`POST /api/v2/buyer/advertisers/{advertiserId}/creatives/create`

Creates a creative manifest scoped to an **advertiser** instead of a campaign.
Use it to stage creative you already have before a campaign exists, or to build
a reusable master you assign to several campaigns later. The manifest is stored
with `campaign_id` unset and `advertiser_id` set, and it appears in
[the advertiser-scoped creative listing](/v2/object-guides/creative#advertiser-scoped-creative-listing).

Everything else about a manifest is the same as the campaign-scoped
[Create creative manifest](/v2/buyer/creatives/tasks/create-creative-manifest):
same `metadata` body, same asset handling, same tracking macros, same 50 MB
per-file and 20-file-per-request limits.

<Note>
  An advertiser-level master does not deliver on its own. It reaches a media buy
  only after it is assigned to a campaign — see
  [Advertiser library: assign and unassign](/v2/object-guides/creative#advertiser-library-assign-and-unassign).
</Note>

## What differs from the campaign-scoped create

|                     | Campaign-scoped                                       | Advertiser-scoped                                                            |
| ------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------- |
| Path                | `/campaigns/{campaignId}/creatives/create`            | `/advertisers/{advertiserId}/creatives/create`                               |
| Scope proof         | The campaign must belong to the authenticated account | The advertiser must belong to the authenticated account                      |
| `format_option_ref` | Accepts `scope: "product"` and `scope: "publisher"`   | `scope: "product"` is rejected — resolving a product option needs a campaign |
| Name uniqueness     | Deduplicated on `(campaign_id, name)`                 | Deduplicated on `(advertiser_id, name)` among non-archived manifests         |
| Delivery            | Propagates to media buys when the campaign executes   | Inert until assigned to a campaign                                           |

## Request

```bash curl theme={null}
curl -X POST https://api.interchange.io/api/v2/buyer/advertisers/10632/creatives/create \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: multipart/form-data" \
  -F 'metadata={
    "name": "Evergreen hero banner",
    "message": "Always-on brand banner",
    "format_kind": "image",
    "linked_assets": [
      { "url": "https://cdn.acme.com/hero-728x90.png", "asset_type": "IMAGE" }
    ],
    "url_assets": [
      { "asset_id": "click_url", "url": "https://acme.com/promo" }
    ]
  };type=application/json'
```

## Parameters

`advertiserId` is a path parameter. The `metadata` JSON part carries the same
fields as the campaign-scoped create:

| Field                  | Type   | Required    | Notes                                                                                                                                                                                                                       |
| ---------------------- | ------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                 | string | No          | Manifest name (max 255). Auto-generated if omitted. Also the dedupe key within this advertiser                                                                                                                              |
| `message`              | string | No          | Creative brief / direction text (max 5000)                                                                                                                                                                                  |
| `format_kind`          | string | Conditional | AdCP 3.1 canonical kind (e.g. `image`, `video_hosted`). Inferred from the one renderable primary asset when omitted; **required** when the create has no such asset — a brief-only, click-URL-only, or `TEXT`-only manifest |
| `format_id`            | object | No          | `{ agent_url, id, width?, height?, duration_ms? }` — legacy ADCP format reference                                                                                                                                           |
| `format_option_ref`    | object | No          | Only `{ scope: "publisher", publisher_domain, format_option_id }` is accepted without a campaign                                                                                                                            |
| `template_id`          | string | No          | Creative template or vendor tag                                                                                                                                                                                             |
| `linked_assets`        | array  | No          | Already-hosted or inline assets (max 50): `{ url` or `data_url, asset_type, content_type?, label?, make_primary? }`                                                                                                         |
| `url_assets`           | array  | No          | Slot-assigned URL assets (max 50): `{ asset_id, url, url_type? }`. Use `asset_id: "click_url"` for the click destination                                                                                                    |
| `url_asset`            | object | No          | Single URL asset: `{ url, url_type }`                                                                                                                                                                                       |
| `text_assets`          | array  | No          | Slot-assigned text assets: `{ asset_id, content }`                                                                                                                                                                          |
| `webhook_asset`        | object | No          | Webhook-backed asset configuration                                                                                                                                                                                          |
| `assets`               | array  | No          | Per-uploaded-file metadata: `{ filename, asset_type?, label?, slot_asset_id? }`                                                                                                                                             |
| `cards`                | array  | No          | Carousel cards for `image_carousel` (2–10)                                                                                                                                                                                  |
| `industry_identifiers` | array  | No          | Industry identifiers per the AdCP spec: `[{ type, value }]`, where `type` is `ad_id`, `isci`, `clearcast_clock`, or `idcrea`                                                                                                |
| `frequencyCaps`        | array  | No          | Buyer-defined caps: `{ max_impressions, window: { interval, unit } }`                                                                                                                                                       |

A create must satisfy two independent requirements, and a request that misses
either is rejected with `400 VALIDATION_ERROR`:

* **Content** — at least one file, `linked_assets` entry, `url_asset`/`url_assets`
  entry, `text_assets` entry, `cards` entry, `webhook_asset`, or a `message`. A
  request carrying only a `name` has none.
* **Format identity** — a canonical `format_kind`, either supplied directly or
  inferred from exactly one renderable primary asset (`IMAGE`, `VIDEO`, `AUDIO`,
  `HTML`, `VAST`). A brief, a click-through URL, and a `TEXT` asset carry no
  identity, so a create built only from those must supply `format_kind`.

`brandAgentId` is accepted in the body for wire compatibility and ignored on
this route — the path `advertiserId` is authoritative.

Form parts: `files=@<path>` (one per uploaded asset). Limits: 50 MB per file,
20 files per request.

## Response

Returns `201` with the same `CreativeManifestResponse` the campaign-scoped
create returns, except `campaign_id` is absent and `advertiser_id` is set:

```json theme={null}
{
  "creative_id": "cm_abcdef",
  "advertiser_id": "10632",
  "name": "Evergreen hero banner",
  "format_kind": "image",
  "assets": [
    {
      "asset_id": "asset_001",
      "name": "hero-728x90",
      "original_filename": "hero-728x90.png",
      "asset_type": "IMAGE",
      "content_type": "image/png",
      "file_size": 18244,
      "public_url": "https://cdn.acme.com/hero-728x90.png",
      "asset_source": "CREATIVE_SOURCE",
      "created_at": "2026-09-01T10:00:00Z"
    }
  ],
  "created_at": "2026-09-01T10:00:00Z",
  "updated_at": "2026-09-01T10:00:00Z"
}
```

When a non-archived manifest with the same `(advertiser_id, name)` already
exists, that manifest is returned with `already_exists: true` and
`ignored_files` set. **The assets sent with that request are not attached to
it** — create under a different name, or use
[Update creative manifest](/v2/buyer/creatives/tasks/update-creative-manifest)
to add assets to the existing one.

## Errors

* `400 VALIDATION_ERROR` — no content supplied (name only), no resolvable
  `format_kind`, a `files` part with no matching `assets[].filename`, more than
  one `make_primary` asset, a file over 50 MB, an unsupported MIME type, or a
  non-numeric `advertiserId`.
* `400 VALIDATION_ERROR` — a product-scoped `format_option_ref`, which cannot
  be resolved without a campaign.
* `404 NOT_FOUND` — `advertiserId` does not exist **or does not belong to the
  authenticated account**. The two cases are deliberately indistinguishable so
  the response never confirms that an advertiser exists in another account.
* `409 CONFLICT` — the name is held by a creative that is still being written
  (`details.reason: name_creation_in_progress`) or was left incomplete by an
  earlier attempt (`name_creation_abandoned`). Branch on `details.reason`, not
  the message.

See [Errors](/v2/reference/errors) for the full error contract.

## From an agent

The `save_creative` MCP tool reaches this operation: omit `creativeId`, supply
`advertiserId` (with no `campaignId`), a `name`, content (`message`, `assets`,
`sourceAssetRef`, or `clickUrl`), and identity (`formatKind`, unless an asset or
private JPEG/PNG source implies it). Supplying `campaignId` instead creates the
Creative under that campaign's advertiser and then attaches it to the campaign.
The tool enforces both requirements before dispatching, so a brief-only call
fails with a named field rather than a generic service error.

`save_creative` sends assets as hosted URLs or inline base64 data URLs; it has
no multipart `files` equivalent. A finalized private JPEG/PNG upload is the
exception: pass its opaque `scope3-asset://v1/...` reference as
`sourceAssetRef`, and Interchange re-verifies and copies the bytes into the
governed Creative store. The manifest keeps only the durable asset and a
one-way source fingerprint, never the private reference, object path, or a
signed URL. Retrying the same source and name returns the same Creative and
completes an interrupted campaign attachment. Package and media-buy attachment
remain separate workflows.

For ordinary `assets`, if the manifest comes back with fewer assets than the
call requested, the tool says so in its response text and sets
`assetAttachWarning`, `assetsRequested`, and `assetsAttached` — the creative
was saved, but the missing media is not on it. Re-send it as a hosted `url`
rather than assuming the creative is complete.

## Related

<CardGroup cols={2}>
  <Card title="Create creative manifest" href="/v2/buyer/creatives/tasks/create-creative-manifest" icon="plus">
    The campaign-scoped create
  </Card>

  <Card title="Creative overview" href="/v2/object-guides/creative" icon="image">
    Manifest fields, the advertiser library, assign and unassign
  </Card>
</CardGroup>
