Skip to main content

Overview

Bring your own creative lets you hand Murph a finished asset — an image, video, or ad tag — directly in a conversation and get it onto a campaign without leaving chat. Instead of navigating to an upload form, you drop the file and answer which campaign is this for? HTML5 bundles also need their landing-page URL before delivery.
This is the chat-first path for creative you already have. To generate creative from a brief instead, see Creative and the creative manifest tasks.
Promoted managed audio has a capability-gated API adoption contract. It is available only when both the account capability and bounded origin are explicitly enabled, and this change enables neither. See Adopt a managed audio source. Even when enabled, it records a creative and optional campaign association only; it never initiates seller or destination delivery, attaches to a media buy, or makes anything live.

The flow

1

Upload the asset

Attach an image, video, tag, or tag sheet in the conversation. Murph recognizes the media kind automatically.
2

Answer “which campaign?”

Murph opens a short picker showing the advertiser and that advertiser’s recent campaigns. You choose where the creative should live:
  • An existing campaign — pick it from the list.
  • A new campaign — describe it in plain language and Murph creates it.
  • Save to the advertiser — park the creative at the advertiser level to assign later. The API and agent equivalent is Create advertiser creative master.
3

Murph maps it to placements

Once the creative is on a campaign, Murph maps it to that campaign’s placements. If an asset lands in the wrong slot, you can remap it. For an HTML5 bundle, add the advertiser destination in the creative’s click-through URL field before media-buy sync.

Uploading large MP4 video

On the shared /mcp/v3 connector, ask to upload a creative and select its advertiser. No destination connection or provider account is required. The upload_creative_asset Task accepts an MP4 up to 2,000,000,000 bytes when managed video is enabled for the buyer. Managed video has its own account-access and service settings; it does not depend on the private JPEG/PNG upload option. Eligible connections also accept JPEG and PNG files up to 30,000,000 bytes. The browser calculates the file’s SHA-256 while streaming it, then uploads the bytes directly to private object storage with a create-only capability. File bytes never enter model or chat context. The signed PUT URL is returned only to the embedded Task app; it is excluded from model-visible results, chat/activity, logs, and persistence. Every Task call rechecks the buyer, advertiser, and exact authenticated principal. The upload capability expires after two hours. Finishing the Task verifies the stored object’s declared type and exact size, pins its immutable storage generation, and waits for asynchronous digest and media inspection. When the exact source is promoted, the app confirms finalization without projecting the private source reference, storage identity, or publication URL into model context. Finalization does not create or attach a Creative. Rejected or abandoned quarantine objects never become public delivery assets.
A finalized V3 buyer-owned MP4 is not yet accepted by save_creative. Do not substitute the legacy provider-bound V2 adoption operation or treat upload finalization as campaign association or destination delivery.
Managed MP4 upload is an alpha available only when the Buyer Account is enrolled. Enrollment can be disabled without changing ad-platform credentials. JPEG and PNG eligibility remains independent.

Turning an uploaded image into a creative

Pass the finalized JPEG or PNG scope3-asset:// reference verbatim as sourceAssetRef to save_creative, plus the matching advertiserId or campaignId. Campaign-scoped adoption derives the owning advertiser from the campaign. For an eligible reference:
Use either campaignId or advertiserId, not both. The upload must be finalized and owned by the same customer, authenticated principal, and advertiser. The server copies the reverified JPEG or PNG bytes into the governed Creative asset store and persists only that durable asset plus a one-way source fingerprint. It never stores the opaque source reference, private object path, or upload/delivery signed URL on the Creative. For a campaign, creation happens in the advertiser library first and the existing campaign-membership operation runs second. Retrying the same source and name returns the Creative already created and completes a missing campaign attachment, without replaying campaign-scoped create side effects. The private upload can then expire without emptying the Creative.

Legacy provider-bound video adoption

An MP4 finalized by the shared V3 buyer Task is owner-bound and upload-only. It cannot currently be passed to save_creative, and the legacy V2 operation below is not a fallback for it. The exact V3 composition contract remains an approval boundary tracked on AI-7473. For a video uploaded through the legacy provider-bound Task, finishing returns the source_uid for the source that passed inspection. That same provider scope can adopt it without assembling a creative around a hosted URL by hand:
campaign_id is optional. Include it and the creative is attached to that campaign in the same call; omit it to keep the creative advertiser-scoped. The campaign and source must match the same advertiser and provider ownership. Attaching also pushes the campaign’s live media buys to their sellers. That push is best-effort and is not part of what the response confirms: a success means the creative is attached to the campaign, not that every seller has accepted it into its packages. Check the media buys themselves to see where the creative is live. The V2 response returns creative_id, source_uid, delivery_url, publication_uid, name, and created. A success that named a campaign_id means the creative is attached to that campaign whether or not this particular call attached it, so a retry safely finishes an interrupted attachment. You name the source, not a URL. The hosted HTTPS URL is issued server-side and resolves the exact file that passed inspection, so the private storage location is never something you supply or can substitute. Adopting the same source twice returns the creative that already exists, with created: false, rather than making a second one. If you include a campaign_id the second time, the existing creative is attached to that campaign — so a call that was interrupted after the creative was made can be retried safely. Retry with the same name: adoption never renames an existing creative, so asking for a different one is refused rather than silently returning a creative that does not have the name you asked for. Names compete among an advertiser’s creatives that are not currently scoped to a campaign — which is how adoption always creates them. If one of those already holds the name, adoption is refused rather than silently reusing it. A creative created directly under a campaign is outside that set while it stays there, but detaching it moves it in: detaching does not free a name, it claims one. Attaching an adopted creative to a campaign afterwards does not release its name either: archiving it does, and so does renaming it with a separate update_creative call. If the creative holding the name is already attached to a campaign, rename it instead — renaming frees the name without disrupting a creative that’s live in a media buy. update_creative is campaign-scoped, so a creative attached to no campaign can only be archived. Note that archiving is the advertiser-scoped delete (archive_creative); the campaign-scoped delete_creative only detaches the creative from that campaign and does not release its name. Duplicating an adopted creative with duplicate_creative copies the video, not the adoption: the copy is not the adoption of record for that source, so it neither blocks nor lets you re-adopt the source through it. A CONFLICT on name does not always mean “pick another name”. Each one carries a details.reason: name_creation_in_progress means another call is still writing that exact name, and retrying the identical request is the right move; name_creation_abandoned means that writer died mid-way, so archive the incomplete creative first; name_taken means the name belongs to a finished creative and you need a different one. The conflicts on source_uid work the same way — adoption_in_progress is the only one worth retrying. adoption_name_mismatch means the source already has a creative under another name; use that name or rename the creative separately. source_delivery_revoked and source_deletion_requested are terminal for that source: upload a new video before adopting again. Branch on details.reason rather than on the message text. Two rules here are enforced by the database, not just checked: a managed video source can back only one live creative, and advertiser-scoped creative names are serialized across both adoption and ordinary creation. Both hold no matter how many callers race, and archiving frees the name.
The delivery_url is not permanent. It stays valid while the source is retained and its delivery has not been revoked. Once the retention window ends, or once the delivery has been revoked with nothing live replacing it, re-adopting that source is refused — with a message telling you what happened, not a name collision. Requesting deletion of the source refuses it too, by taking the source out of the adoptable state. None of these can be refreshed in place: upload a new video and adopt that new source, usually under a new name, since the existing creative still holds its old video until you archive or rename it. A deletion request also stops a call that was only trying to finish an interrupted attachment — a source you have asked us to erase is not attached to anything further.
If the source is already held by a creative but adoption can no longer confirm that creative still carries the video — because its asset was replaced or removed directly on that creative — adoption refuses with CONFLICT rather than creating a second creative for the same source. Archive the creative holding it and adopt again, or upload the video again and adopt the new source. A second CONFLICT also tells you to archive, for a different reason: an earlier adoption of this same source left its creation marker uncleared and has been stuck long enough (about fifteen minutes) that nothing is still writing it. An asset row may already have landed, but the creative never finalized. Its details.reason is adoption_abandoned; archive that incomplete creative and adopt again. Within these three source-identity conflicts, adoption_in_progress is the one you should simply retry. It means another adoption is still finishing or the blocking adoption changed while this request was classifying it; retrying lets the request observe the settled state. The separate name_creation_in_progress reason described above is also retryable. Branch on details.reason, never on the message; the other reasons require archiving or changing the request first. Legacy adoption produces a creative and may enqueue existing V2 campaign sync behavior; its success response proves neither provider creation nor acceptance. Only exact provider readback confirms destination materialization. For the production-dark managed-audio contract, see Adopt a managed audio source. Adoption is available wherever direct video upload is already enabled for your account — it is part of that alpha, not a separate opt-in. A request from an account without it is refused with CAPABILITY_NOT_SUPPORTED.

Uploading HTML5 banner ZIPs

Some ad tools export one HTML5 banner as a ZIP containing an index.html file and its scripts, styles, images, and fonts. Upload that package as-is in buyer chat. Murph keeps the files together as one HTML5 creative instead of creating a separate creative for each file. Murph records the dimensions when the package declares one unambiguous ad.size. It also recognizes common wrapper exports that contain one nested HTML5 ZIP, an exact exploded copy, and an explicitly named same-size backup image. The nested package is retained unchanged. Ambiguous, malformed, oversized, or unsafe archives are rejected rather than partially imported. Importing and delivering are separate checks. Before media-buy sync, an HTML5 creative needs an explicit landing-page URL. A seller option that declares an HTML5 behavior constraint Murph cannot prove from inspection is rejected with that constraint named instead of being sent optimistically. Add the destination in the creative’s click-through URL field before syncing the media buy.

Uploading tag sheets

Murph accepts creative manifests in CSV, legacy XLS, and XLSX. CM360/DCM tag sheets can include instructions before the data table and several alternative tag implementations for one placement-tag row; Murph finds the actual header and creates one creative per populated display row rather than attaching every display alternative as a duplicate. For display, Murph prefers the iframe/JavaScript implementation and uses JavaScript or Standard as fallbacks. It retains every populated display, VAST pre-fetch, and Internal Redirect alternative as inert source provenance. Inline third-party markup is stored as a non-trafficable custom creative without rewriting vendor macros. Murph does not mislabel it as canonical display_tag (which requires a hosted tag URL) or as an HTML5 bundle. A sheet containing only destination-sensitive alternatives is recognized but not converted into an arbitrary primary creative. VAST version must match the destination player, while Internal Redirect requires separate image and click URL fields in a compatible ad server. When modern and legacy sheets contain the same placement name and size, the modern row takes precedence; unmatched legacy rows are retained. Declared dimensions such as 300x250 are retained for destination compilation. Murph can also read dimensions from common tag markup, including HTML attributes, CM360 inline styles, and sz= parameters. A dimension declared in the sheet takes precedence over a size inferred from markup.

Preview and improve the mapping

Use the Inspect a Tag Sheet skill to preview a CSV, XLS, or XLSX file locally before upload. Its offline inspector returns the parser version, mapping-profile version, mode, creative-row count, canonical role and rule IDs, and diagnostic codes. The receipt contains no filename, worksheet name, source header, placement name, tag, URL, formula, or cell value. The mapping profile is versioned. When the production parser can read a workbook but finds no usable rows, Interchange automatically records the same content-free receipt. When that shape recurs across customers, it sends one deduplicated, content-free signal for team review. Corrupt files and size-limit failures are recorded for diagnosis but do not automatically become product work. Destination-sensitive rows are recognized and require a compatible destination before trafficking. A team member or authorized agent reviews the signal, reproduces it with synthetic or explicitly approved sanitized data, adds a regression fixture, and publishes a new profile version. If local inspection finds a plausible but incorrect result, such as the wrong row count, the skill can prepare the same sanitized receipt for support. It asks for confirmation before filing and never sends the workbook or its contents. Customer workbooks do not enter the shared test corpus by default.

Uploading before you’ve named an advertiser

You don’t have to know the advertiser first. If you drop a file at the start of a conversation, Murph stashes it and holds onto it across turns. The moment you name (or pick) an advertiser, the stashed upload is adopted into the “which campaign?” picker — nothing is lost between the upload and the decision.

What happens to your creative

  • The asset is stored against your advertiser and, once routed, attached to the chosen campaign.
  • A creative saved to the advertiser (rather than a campaign) waits there until you assign it — it is not sent to any seller until it’s on a live campaign.
  • Attaching to a campaign makes the creative eligible to enter delivery; it must still clear any storefront and source-system approval gates before it can serve. Saving to the advertiser or stashing does not begin that process.