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

# Creative Engines

> Discover Creative Engines, save a campaign creative session, and explicitly generate or refine its variants through V3 MCP tools.

<Note>
  This alpha V3 MCP contract is available only to enrolled Buyer Accounts. It
  adds discovery, connection setup, campaign-scoped session reads, durable
  session saves, and explicit generation or refinement for registered Creative
  Engines. The Creative Engines Page is available for enrolled Buyer Accounts.
  Provider qualification and the end-to-end buyer journey remain separate work.
</Note>

Creative Engines gates generation and refinement, not assembly. Any authorized
buyer can use the Creative Library to assemble a draft in a campaign Creative
Session by choosing a format, filling slots, adding a name and click-through
URL, and saving. This does not create a Creative. When Creative Engines is not
enabled, the composer leaves those assembly controls available and asks your
Apostra account team to enable it for the Buyer Account. When Creative Engines
is enabled but the draft has no connected engine, the composer says generation
needs a connected Creative Engine on the draft.

Your Apostra account team enables Creative Engines for enrolled Buyer Accounts.
Contact them to ask about enrollment.

An engine is a creative service you can discover and connect. A connection is your authorization
grant to that service. One engine can have several connections, each with its
own credential and provider accounts.

## Open Creative Engines in Murph

In Murph, select **Creative Engines** in the Discover section of the Buyer
navigation. The entry is shown only when Creative Engines is enabled for the
active Buyer Account. It opens the same Page and does not grant access by
itself.

You can also ask Murph to find a registered provider and open its connection
setup on the Page; you start the secure connection there.

## Discover an engine

Call `search` with `kind: "creative_engine"`. Use `query` to match an engine or
provider name, `filter.ids` for up to 50 exact engine IDs, and `limit` plus the
returned `cursor` to page results. IDs are positive integer strings.

```json theme={null}
{ "kind": "creative_engine", "limit": 20 }
```

Results contain one record per engine, including its name, description,
provider, authentication modes and your existing grants. The `capabilities`
declaration lists modalities, transformer IDs, supported format IDs and
build/preview support when the registered adapter supplies them. `get` with
the same kind and an engine `id` returns one record.

Declarations describe support; they are not a live provider health check or
proof of access to every model. Grant status describes your connection state.
`pricing: null` means this read has not obtained a quote, not that generation
is free. The current `supportedFormatIds` are adapter format identifiers, not
canonical AdCP format declarations or executable capability IDs.

Discovery currently covers registered Creative Engines visible to the active
buyer. Arbitrary external MCP endpoints cannot be added through this preview.

## Authorize and manage a connection

Use `open_creative_engines_page` to open the Creative Engines Page in an MCP
Apps host. The Page has Connected and Available views. It separates declared
capability from observed connection state and account access, and shows when no
provider price has been quoted. It supports secure connection repair, account
selection, advertiser mapping, and disconnect. It does not expose provider
credentials, accept an arbitrary MCP URL, quote a price, or start generation.

Pass `connectionAction: "connect"` with a registered `engineId` to focus that
engine's secure setup control. This opens no authorization handoff by itself:
the buyer starts setup from the Page.

Call `save_connection` with exactly one change. To begin authorization:

```json theme={null}
{
  "target": { "kind": "creative_engine", "id": "90" },
  "authorization": {}
}
```

The result contains a secure authorization handoff. Open it to complete OAuth
or enter a bearer credential, according to the engine's supported modes. Never
put a provider token into tool arguments. The tool does not return token values.

The browser handoff identifies the registered provider. In the OpenAI
customer-key form, it asks for an **OpenAI API key** and links to the official
[OpenAI API key dashboard](https://platform.openai.com/api-keys). This is an
explicit customer-key connection only; it does not configure a platform-managed
credential or authorize generation spending.

To list your creative grants:

```json theme={null}
{ "kind": "connection", "filter": { "targetKind": "creative_engine" } }
```

Read a grant with `get({"kind":"connection","id":"77"})`. It includes safe
credential status, selected account, advertiser mappings and a bounded account list. Use
`connectionAccountsOffset` with the returned `accountsPage.nextOffset` for
another account page. Provider metadata and secrets are omitted.

Use the existing `save_connection` fields with `connectionId` to reconnect
(`authorization`), refresh accounts (`refreshAccounts: true`), select a provider
account (`selectedAccountId`), map an advertiser (`advertiserMapping`), or disconnect (`state: "removed"`). A connection
cannot change its target. Disconnect retries remain available for owned grants
after catalog delisting or preview enrollment is removed.

Creative connections do not accept seller selection, advertiser activation,
media billing, buying policy or Enhanced Reporting.
Signup-restricted credentials cannot use the creative preview.

AudioStack and ElevenLabs require an advertiser mapping before generation. This
selects the provider organization or workspace that pays for the request. Use
`advertiserMapping: {state: "mapped", advertiserId: "42", accountId: "88"}`
with the connection ID. Read `accountMappings` to find the link ID for unmapping;
use `connectionMappingsOffset` with `accountMappingsPage.nextOffset` for another
mapping page. Replacing the provider key requires remapping the advertiser.

## Generation and funding

This alpha provides discovery, setup, session reads and the two Creative
Session operations. `save_creative_session` saves a brief, selected output,
approval or finalisation but never starts generation. `generate_variants`
explicitly prepares and executes one saved session revision. These are
generation operations and require Creative Engines. Keep the chosen engine,
provider account and advertiser explicit when moving from setup into a session.
A connection alone does not authorize spending.

The operations do not provide a request estimate or turn an unknown catalog
price into a quote. For accounts and clients with the existing V2 generation
tools, use the [generative creative workflow](/v2/buyer/creatives/generative-creative).

Use the generation workflow's applicable funding and price information before
requesting paid work. The current catalog's `pricing: null` cannot be used as a
quote. Customer-key eligibility and provider account requirements still apply;
see [provider setup](/v2/buyer/creatives/generative-creative). A failed
customer-key request does not authorize switching to a platform-funded request.

During iteration, preserve the brief, reference assets, target format and
parent variant. Retain returned session and task IDs so an interrupted request
can resume without submitting another build. Review the exact output that will
be finalized, then read back the saved creative. Content acceptance remains
separate from [seller review](/v2/buyer/creatives/approval) and campaign launch.

## Existing seller integrations

`search({"kind":"connection"})` continues to list seller grants by default.
Seller grants gain `target: {kind: "seller", id: "..."}` and retain `sellerId`.
Existing `save_connection` calls using `sellerId` continue to work; new callers
can use a seller target instead. Supplying conflicting fields fails validation.

You can continue making creative directly with a provider and
[bring that creative into Apostra](/v2/buyer/creatives/bring-your-own-creative).
This alpha does not change that workflow or start a generation job without an
explicit `generate_variants` call.

## Read a creative session

A creative session holds work in progress: the brief, plan, variants, evaluation,
selection and any finalized creative. Reading it does not start generation.

List sessions within one campaign:

```json theme={null}
{ "kind": "creative_session", "filter": { "campaignId": "42" }, "limit": 25 }
```

Use `filter.status` to choose `drafting`, `refining`, `evaluating` or `finalized`.
The limit is at most 100. Results contain session IDs, campaign IDs, titles,
statuses and revisions. When `nextCursor` is present, pass it as `cursor` with
that same campaign and status filter. Each page reflects current state; the
list does not promise a fixed snapshot or a total count. Text queries and
other filters are not supported for sessions.

Open a result with its campaign as `sourceId`:

```json theme={null}
{ "kind": "creative_session", "id": "cs_example", "sourceId": "42" }
```

The object includes its persisted `revision`, plan, variants and evaluation.
The read returns the selected variant and the latest session history first. It
does not return inline asset data. If a session has more history or detail than
one tool response can carry, `truncated: true` and `omitted` identify the
bounded fields; use the existing V2 workflow for the complete durable record.
When the session has a saved engine connection, `engine` contains its
`engineId` and `connectionId`. Credential material is not included.
Hosted image, audio and video plans can identify their format with
`format_kind` (`image`, `audio_hosted` or `video_hosted`) and `params`, without
an agent URL. Image dimensions use `params.width` and `params.height`;
an exact audio duration uses `params.duration_ms_exact`. The declared modality
must match the selected engine. A canonical declaration cannot also specify a
legacy target format. Explicit legacy format requests retain their existing
compatibility path.
When preparing image placement renders, the session uses each placement's
resolved dimensions. A placement without dimensions returns a warning instead
of generating at the original image size. These renders still need the
applicable seller compatibility checks before delivery.

Session reads do not support `include`. Both reads require current access to
the campaign and advertiser, and expired sessions are unavailable.

`save_creative_session` saves a campaign brief and locked references, selects
or approves one exact output, and finalises that approved output. Saving does
not start generation. `generate_variants` is the separate explicit action for
one saved revision. Reuse its `actionKey` only for an identical retry; name the
parent output and feedback when refining. Both operations require the Creative
Engines account capability and a saved engine connection. Generation can
remain submitted or uncertain while its original task or receipt is recovered;
it never silently submits a replacement request.

Both operation responses include the current `session`, `revision`, and, when
present, `sessionGeneration`. Generation also returns its `actionId` and each
leaf's status, task ID, and variant IDs; approval and finalisation controls
remain in the session. Session detail is bounded in these responses. When
`sessionTruncated: true` is present, `sessionOmitted` identifies omitted
detail, while the returned action and retry controls remain exact. The durable
session history is not paginated by these operations; use the existing V2
creative-session workflow to retrieve the complete record.

If already-persisted action controls alone cannot fit in one response, the
operation returns a bounded recovery error instead of clipping those IDs. Read
the durable session before retrying the same saved action; this does not create
a replacement generation request.
