Creative MCP

Ad creative refresh

When paid social or display ads go stale (ad fatigue: frequency up, CTR down), an agent briefs and generates fresh on-brand ad image variants with Brandiseer for each placement (square feed, vertical story/reel, landscape display, seasonal or offer variant); a person then downloads imageUrl and uploads it in Meta Ads Manager or Google Ads, or an agent with the advertiser's own API credentials uploads the image into the ad account's image library. Brandiseer does not create, edit, launch, or pause ads or campaigns, does not read ad performance, and does not sync.

~25 to 40 min setup
  • MCP
  • REST
  • Cursor
  • Cowork

Brandiseer + Meta Ads Manager + Google Ads (+ Cursor or Claude Cowork)

Cover: a fatigued ad replaced by a fresh on-brand set

By the end of this guide you will have a repeatable way to refresh stale paid social and display images. An agent in Cursor or Claude Cowork calls Brandiseer and gets an imageUrl for a square feed, a vertical Story or Reel, a landscape display frame, or a seasonal or offer variant of one of those placements. A person then downloads that file and uploads it in Meta Ads Manager or Google Ads.

Brandiseer owns the brand memory and the still. Meta Ads Manager owns Feed, Stories, and Reels, plus the ad, the ad set, and the campaign. Google Ads owns Display and Performance Max, plus the ad and the campaign. Brandiseer returns imageUrl only. It does not create, edit, launch, or pause ads, campaigns, ad sets, or creatives. It does not read ad metrics. It does not sync. There is no Brandiseer Meta app in this guide, no Brandiseer Google Ads app, and no ads MCP. Do not invent any of them.

The default handoff is a person. They download imageUrl and upload it as a new ad image or image asset, then build or swap the ad and launch the test themselves. Optionally, an agent that already holds the advertiser's own credentials can upload the image bytes into that ad account's image library and stop there. A Meta upload returns an image hash. A Google Ads upload returns an asset resource name. A person still reviews the image and launches. Spotting fatigue is also a person: they read their own Ads Manager or Google Ads reporting, or they paste the numbers into the brief. The agent does not read frequency or CTR through Brandiseer.

People who need on-brand stills for Google Slides or Drive should use Drive & Slides deck visuals. People who keep issue and project stills in Linear should use Linear issue visuals. People who keep campaign records in Airtable should use Airtable record visuals. People who brief stills inside Slack should use Slack creative desk. Organic captions and Buffer scheduling should use Social media automation. That guide posts organically through Buffer. It is not paid ads, and this guide does not schedule or publish posts. Schedules and webhooks in Zapier, Make, or n8n should use Always-on creative automation. Webflow site stills should use Webflow site visuals. WordPress Media Library stills should use WordPress site visuals. Framer site stills should use Framer site visuals. This guide does not recreate any of those.

Who it's for

  • Performance marketers, founders, and in-house media teams whose paid social or display ads have gone stale and who need fresh on-brand images without opening a separate design tool for every placement
  • Agencies that keep one Brandiseer Brand ID per client and one Meta ad account or Google Ads account per client
  • Operators who can download an imageUrl and upload it in Ads Manager or Google Ads, or who already give an agent the advertiser's own API credentials and want that agent to stop at the image library

Ideal customer profile: a team whose paid ads already live in Meta Ads Manager or Google Ads, whose brand already lives in Brandiseer, and whose missing piece is a brand-safe image variant plus a clear handoff into the ad account. The person still decides what launches.

Why Brandiseer in this stack

Meta Ads Manager and Google Ads are where the ad account, the placements, and the launch live. Cursor or Cowork is the agent that turns a brief into stills. Brandiseer stores the logo and visual identity once, then applies that memory on every image. The prompt carries subject, layout, composition, and on-image text. It does not restate colours, fonts, mood, or visual style.

A refresh drifts when every new ad image is a one-off export from a general image tool. Brandiseer keeps the still on the same brand as the rest of the work. The ad platform still decides which ad, which placement, and which test go live. Brandiseer does not see frequency, CTR, or spend, and it does not turn an image into a live ad.

This is a different job from the sibling guides:

Example strip: square feed, vertical story, landscape banner, and a seasonal variant

Stack

LayerToolRole
Brand visualsBrandiseer MCP and/or REST v2Generate on-brand ad images. MCP uses Authorization: Bearer. REST uses X-API-Key: bds_...
Agent host (pick one)CursorRead the brief, call Brandiseer, return imageUrl and a placement note
Agent host (pick one)Claude CoworkSame contract as Cursor for interactive ad images
Paid socialMeta Ads ManagerFeed, Stories, and Reels. A person uploads and launches by default. Optional image library upload with the advertiser's own Marketing API token
Paid displayGoogle AdsDisplay and Performance Max image assets. A person uploads and launches by default. Optional image asset upload with the advertiser's own developer token and OAuth

Stack diagram: Cursor or Cowork, Brandiseer, and Meta Ads plus Google Ads

You only need one agent host. The Brandiseer contract is the same on both. There is no Brandiseer app that creates an ad in Meta or Google. The handoff is an image URL, a download, or an image-library call that you perform with the advertiser's own API. This guide does not use an ads MCP. Do not invent one.

Brandiseer docs: Developers · guide/docs · guide/image · Settings → API

Meta docs: Ad account ad images · Instagram ads media requirements · Marketing API authorization

Google Ads docs: REST auth · REST examples, upload binary assets · Working with assets · Performance Max asset requirements · ImageAsset

Endpoint tables and HTTP contracts are in API reference at the end of this guide.

Meta Ads Manager and Google Ads (placement, not generation)

Three practical paths. Use the first one until an image-library write is actually needed. Brandiseer is finished when it returns imageUrl.

  1. Ads Manager or Google Ads UI (default). Download the file or open imageUrl. Upload it as a new ad image in Meta Ads Manager, or as an image asset in Google Ads. Then build or swap the ad and launch the test yourself. Brandiseer stops at the URL. The ad platform stores its own copy. A person always reviews and launches.
  2. Meta image library (optional agent path). Only with the advertiser's own Marketing API access token, and only to upload bytes. The call is POST /act_{ad_account_id}/adimages with the image as base64 bytes. The response struct includes hash. That hash is an image-library id a person, or their own tooling, can use later. This guide does not create a creative, an ad, an ad set, or a campaign.
  3. Google Ads image asset (optional agent path). Only with the advertiser's own Google Ads developer token plus OAuth. The call is customers/{customerId}/assets:mutate with type IMAGE and imageAsset.data set to the raw image bytes (base64 in JSON). The mutate result includes the new asset's resource name. This guide does not link that asset to a campaign, an ad group, or an asset group, and it does not create or pause an ad.

ad_account_id, the Google Ads customer id, and which placement to refresh come from the human. Do not guess them. Do not read them from Brandiseer. Brandiseer does not hold Meta or Google credentials.

A person still reviews the image and launches the test.

How it works

Architecture, from a stale ad to a fresh image the person can test:

  1. Spot fatigue. A person reads frequency and CTR in their own Meta Ads Manager or Google Ads reporting, or pastes those numbers into the brief. The agent does not pull ad performance through Brandiseer. There is no ads connection that reads metrics.
  2. Brief variants. You name the placement: square feed, Stories or Reels, landscape display, or a seasonal or offer variant of one of those. Ask for 3 to 4 variants per placement. The agent rewrites each brief into subject, layout, and on-image text. It does not invent a price or an offer.
  3. Generate. The agent calls Brandiseer with aspectRatio, resolution, mode, and useLogo as fields. Square feed uses 1:1. Stories and Reels use 9:16. Landscape display uses 16:9. Prefer design and 2K.
  4. imageUrl to ad library. Brandiseer returns imageUrl only. A person downloads it and uploads it in Ads Manager or Google Ads. Optionally, an agent with the advertiser's own credentials uploads the bytes into the image library and reports the Meta hash or the Google Ads resource name. It does not claim an ad changed.
  5. Human launches and tests. A person builds or swaps the ad, launches the test, and reads the result in the ad platform. Brandiseer does not launch, pause, or judge the test.

Workflow infographic: spot fatigue, brief variants, generate, imageUrl to ad library, human launches and tests

Connect the workflow

Give the agent access to Brandiseer

Create an API key for the runnable setup, or connect the hosted MCP endpoint when your agent supports MCP.

What you need

  • Company website URL, if the brand is not in Brandiseer yet
  • Brandiseer account with at least one finished brand profile
  • API key (bds_...) from Settings → API or Developers
  • Brand ID (bds_c_...) for every brand the agent may call
  • Credits for the stills you actually generate (see the table in Limits & FAQ)
  • Cursor or Claude Cowork, with Brandiseer MCP or a way to call REST
  • A Meta ad account, a Google Ads account, or both, that you can upload images into
  • The placement you are refreshing, and any on-image line you actually want printed (price, offer, or seasonal line). If you do not supply that line, the image stays free of one
  • For any Meta library upload: the numeric ad account id and the advertiser's own Marketing API OAuth access token, in the secret store. Brandiseer is not the Meta app
  • For any Google Ads library upload: the customer id (digits only, no hyphens), a Google Ads developer token from a manager account, and an OAuth access token with scope https://www.googleapis.com/auth/adwords. Brandiseer does not issue the developer token
  • Store the Brandiseer key and any ad-platform credential in the agent secret store. Never in an ad, a prompt you commit, Slack, or git

Setup

Stage 1: Add your brand on Brandiseer

  1. Go to brandiseer.com. In the homepage input, enter your company website URL and click Try My Brand.
  2. Wait about one minute while Brandiseer analyses the site and picks a logo and visuals.
  3. Review those visuals carefully. They teach Brandiseer your look. Every later ad image is influenced by what you leave here.
  4. Remove anything off-brand (partner logos, stock, irrelevant screenshots). Add campaign creatives or product photography that match the look you want.
  5. Click Add Brand, sign up if prompted, then wait about 30 seconds for the brand profile to finish.

Agencies repeat this once per client. Do not point two client ad accounts at one Brand ID.

Stage 2: API key and Brand ID

  1. Open brandiseer.com/developers or Settings → API.
  2. Create an API key (bds_...). Put it in the agent host's secret store. Do not paste it into an ad, a doc, Slack, or a git repo.
  3. Copy the Brand ID (bds_c_...).
  4. Confirm the key with GET https://brandiseer.com/api/v1/credits and GET https://brandiseer.com/api/v1/brands, header X-API-Key. The credits JSON includes credits. The brands list includes each brand id.
  5. Optional reachability check, no key required: GET https://brandiseer.com/api/v1/health returns { "status": "ok" }.

Read guide/docs and guide/image once while you write the standing instructions. Those pages are the live contract if a field name ever moves.

Stage 3: Connect Brandiseer to the agent host

Use Cursor or Cowork. One host is enough.

A. MCP

  1. Add the Brandiseer MCP server at https://brandiseer.com/api/mcp.
  2. Authenticate with Authorization: Bearer and the API key, in the secret field your host provides.
  3. Confirm the tool list shows brandiseer_list_brands, brandiseer_check_credits, and brandiseer_generate_image. If a fourth Brandiseer tool appears, ignore it until guide/docs documents it.

B. REST

  1. On Developers, open View Docs and use Copy for LLM if you want the reference inside the session.
  2. Tell the agent to prefer POST https://brandiseer.com/api/v2/generate or POST https://brandiseer.com/api/v2/generate/async with X-API-Key.
  3. If Design mode times out, switch that call to async and poll GET https://brandiseer.com/api/v2/jobs/:jobId every 3 to 5 seconds.

Stage 4: Save the standing instructions

  1. Paste the System prompt from this guide into the Cursor rule or Cowork instructions that will run ad image refreshes.
  2. Fill the defaults the prompt asks for: Brand ID, default crops per placement, resolution, mode, and whether useLogo is on when the brief is silent.
  3. If image-library writes are in scope, also note that the Meta token or the Google Ads developer token and OAuth token live in the secret store. Leave the ad account id and the customer id blank until the human names them.
  4. Ask the agent to call brandiseer_list_brands (or GET /api/v1/brands) and confirm the Brand ID exists before the first paid still.

Stage 5: Smoke test one feed image in the Ads Manager UI

  1. Ask for one square feed image with a layout-only brief (the spring feed image in Example flows). Do not ask the agent to read your ad account.
  2. Confirm the agent checked the brand, avoided colour and mood words, did not invent a price or offer, and returned imageUrl plus crop and mode.
  3. Download that file. In Meta Ads Manager, upload it as a new ad image, or in Google Ads upload it as an image asset. Confirm the image shows in the library.
  4. Do not launch an ad if you are only proving the handoff. Leave the test for a person after the image looks right.
  5. Send a second brief that only says "make the ad premium and moody". The agent should ask what is physically in the frame instead of generating.

Stage 6: Optional image-library upload

Skip this stage if people will upload stills by hand. Use it only when the advertiser's own credential is already in the secret store and the human named the account. Stop when the library accepts the file. Do not create, edit, launch, or pause an ad.

Meta Marketing API

  1. Use an app and an OAuth access token the advertiser already owns. Brandiseer is not that app and does not mint the token. See Marketing API authorization.
  2. Download the PNG bytes from imageUrl. Base64-encode those bytes.
  3. POST https://graph.facebook.com/v25.0/act_{ad_account_id}/adimages. The adimages reference checked for this guide lists v25.0 as the current version on that page. ad_account_id is the numeric id, so the path contains the act_ prefix. The documented body parameter for the file is bytes, a base64 string. copy_from copies an image between ad accounts. Do not use it to upload a new Brandiseer file. See Ad account ad images.
  4. Marketing API reference examples pass the OAuth token as the form field access_token. A 190 on this edge means invalid OAuth 2.0 access token. A 200 means permissions error.
  5. Read hash from the image struct under images. Keep that hash for the person. Do not call an ad creative, ad, ad set, or campaign endpoint.

Google Ads API

  1. You need both a developer token and an OAuth access token. The developer token is sent on every call in the developer-token header. A manager account finds it at ads.google.com/aw/apicenter. The OAuth scope is https://www.googleapis.com/auth/adwords. Brandiseer does not create the Google Cloud client and does not hold the developer token. See REST auth.
  2. Download the PNG bytes from imageUrl. Base64-encode those bytes. imageAsset.data is the raw bytes, not the Brandiseer URL.
  3. POST https://googleads.googleapis.com/v25/customers/{customerId}/assets:mutate with Content-Type: application/json, Authorization: Bearer ACCESS_TOKEN, and developer-token. Customer ids have no hyphens (1234567890, not 123-456-7890). If a manager account is calling a client account, also send login-customer-id with the manager's customer id. If the OAuth user is a direct user of the target client, omit login-customer-id. The REST examples page checked for this guide uses version 25. See Upload binary assets.
  4. Body: one operations item whose create sets name, type to IMAGE, and imageAsset.data to the base64 bytes. Use a unique descriptive name. The mutate result includes the new asset's resource name. Image assets cannot be changed or removed programmatically after upload. See Working with assets.
  5. Stop. Do not link the asset to a campaign, an ad group, or a Performance Max asset group. A 16:9 Brandiseer file is not a 1.91:1 landscape marketing image. The person crops before they use it that way, then launches themselves.

Prompting rules for Brandiseer images

When the agent builds prompt:

  • Keep subject, layout, composition, and on-image text (what the words say and where they sit).
  • Never send brand colours, fonts, mood, or visual style. Brand memory already applies those. Style words fight the brand and produce off-brand stills.
  • Put crop in aspectRatio, quality in mode, pixel size in resolution, and logo on/off in useLogo. Those are body fields, not prompt prose.
  • Keep on-image text short. One short line is enough. Leave it out when the ad headline will live in the ad platform, not on the image.
  • Do not invent a price, a discount, a date, or an offer. If the human did not supply the exact line, the image has no offer text.
  • On 9:16, leave an empty band at the top and an empty band at the bottom so Stories and Reels UI (profile, buttons, captions) does not cover the subject. Stories and Reels safe zones differ. This guide does not invent a pixel inset. Keep the subject in the middle band.
  • Map the placement to a documented Brandiseer ratio. Supported values are 1:1, 16:9, 9:16, and 4:3. Square feed: 1:1. Stories or Reels: 9:16. Landscape display: 16:9. Seasonal or offer variant: the same ratio as the placement it refreshes.
  • Feed portrait 4:5 is not a Brandiseer aspectRatio. Do not send 4:5. If the human wants a 4:5 feed crop, generate 9:16 and let them crop, or stay on 1:1 for the square feed. Say which one you used.
  • Google Display and Performance Max landscape marketing images are 1.91:1 (recommended 1200 by 628, minimum 600 by 314). Brandiseer has no 1.91:1 ratio. Generate 16:9 and let the person crop. Square marketing images are 1:1, which Brandiseer can generate directly. The ratio is checked when someone later links the asset, not during the library upload. See Performance Max asset requirements.
  • 4:3 is a real Brandiseer ratio. None of the placements above require it. Use 4:3 only when the human asks for that frame.
  • For a test set, generate 3 to 4 variants per placement. Change what is in the frame or how it is arranged. Do not differentiate variants with colour, mood, or an invented offer.
  • Prefer design for finished ad images. fast is the API default if you omit mode, and it is the right fallback if a design job fails once.
  • Prefer 2K for these stills. Use 1K when file size or speed matters. Use 4K only when the brief asks for it.
  • Set useLogo true only when the brief asked for a logo (or your default says so).
  • Full rules: Prompt compatibility.

System prompt

Paste this into Cursor or Cowork as the standing instructions for ad image refreshes. Replace the placeholders before the first generate.

Copy-ready
You generate on-brand ad images for paid social and display placements.
Brandiseer returns an image URL. You do not create, edit, launch, or pause
ads, campaigns, ad sets, or creatives. You do not read ad metrics. You do
not sync Meta or Google Ads. You do not claim an ad account changed unless
an image-library call you actually performed returned success.

Brandiseer:
- MCP: https://brandiseer.com/api/mcp with Authorization: Bearer.
  Tools you may call: brandiseer_list_brands, brandiseer_check_credits,
  brandiseer_generate_image. Do not invent tool names.
- REST: X-API-Key: bds_... (secret store only).
  Prefer POST https://brandiseer.com/api/v2/generate
  or POST https://brandiseer.com/api/v2/generate/async
  then poll GET https://brandiseer.com/api/v2/jobs/:jobId every 3 to 5 seconds
  until data.status is done or failed, or about 10 minutes have passed.
- Live contract: https://brandiseer.com/guide/docs and
  https://brandiseer.com/guide/image
- Supported aspectRatio values: 1:1, 16:9, 9:16, 4:3. Do not send 4:5
  or 1.91:1. Brandiseer does not host a Meta app or a Google Ads app.
  There is no ads MCP.

Defaults for this workspace (fill in once):
- Brand ID: bds_c_...
- Square feed aspectRatio: 1:1
- Stories or Reels aspectRatio: 9:16
- Landscape display aspectRatio: 16:9
- Seasonal or offer variant: same ratio as the placement it refreshes
- Feed portrait 4:5: not supported. Ask, then use 9:16 for a crop the
  human will make, or stay on 1:1. Never send 4:5.
- mode: design
- resolution: 2K (use 1K if file size or speed matters)
- useLogo when the brief is silent: false
- Variants per placement when the human asks for a test set: 3 to 4
- Multi-brand map, if any: brand name to bds_c_...

On every request:
1. Resolve brandId from the brief or the default. If more than one brand
   exists and the brief does not name one, ask. Never fall through to
   another client's Brand ID.
2. Fatigue numbers (frequency, CTR, spend) come from the human. Do not
   call an ads API to read performance. If the brief has no placement,
   ask which one. Do not invent the account.
3. Check credits before a batch (brandiseer_check_credits or
   GET https://brandiseer.com/api/v1/credits). A single still can proceed
   if the last known balance covers the mode and resolution in the table
   you were given. On 402, stop.
4. Rewrite the brief into subject, layout, composition, and on-image text.
   Strip colours, fonts, mood, and visual style. If stripping leaves no
   physical subject, ask what is in the frame. Do not generate.
5. On-image text stays short. Use only a line the human supplied. If they
   did not give a price, discount, date, or offer, do not invent one.
   On 9:16, keep the subject in the middle band and leave empty bands at
   the top and bottom.
6. Choose aspectRatio from the placement. Put resolution, mode, and
   useLogo in API fields, not in the prompt. Square feed is 1:1. Stories
   or Reels are 9:16. Landscape display is 16:9. Use 4:3 only when the
   human names that frame.
7. Generate one still per variant. Return imageUrl, aspectRatio, mode,
   resolution, useLogo, and a placement note: which account and placement
   the human named, and which path (Ads Manager or Google Ads UI upload,
   Meta adimages hash, or Google Ads asset resource name).
8. Do not tell the user an ad, campaign, or library changed unless the
   library call you actually performed returned success.

Image library, only when the human already asked for it:
- Default path: the human downloads imageUrl and uploads it in Meta Ads
  Manager or Google Ads, then builds or swaps the ad and launches the
  test. You do not claim that happened. You do not launch.
- Meta, library upload only:
  POST https://graph.facebook.com/v25.0/act_{ad_account_id}/adimages
  Parameter bytes: base64 of the PNG downloaded from imageUrl.
  Do not use copy_from for a new file.
  Pass the advertiser's own OAuth access token. Marketing API reference
  examples send it as the form field access_token.
  Read hash from the struct under images. Stop. Do not create a creative,
  ad, ad set, or campaign.
  Docs: https://developers.facebook.com/docs/marketing-api/reference/ad-account/adimages/
- Google Ads, library upload only:
  Headers: Authorization: Bearer ACCESS_TOKEN, developer-token, and
  login-customer-id only when a manager is calling a client account.
  Scope: https://www.googleapis.com/auth/adwords
  Customer ids have no hyphens.
  POST https://googleads.googleapis.com/v25/customers/{customerId}/assets:mutate
  create.type = IMAGE
  create.imageAsset.data = base64 raw bytes (not the imageUrl string)
  create.name = a unique descriptive name
  Keep the resource name from the mutate result. Stop. Do not link the
  asset and do not create an ad. A 16:9 file still needs a human crop
  before it is used as a 1.91:1 landscape marketing image.
  Docs: https://developers.google.com/google-ads/api/rest/auth
  https://developers.google.com/google-ads/api/rest/examples
  https://developers.google.com/google-ads/api/docs/assets/working-with-assets

Out of scope:
- Reading frequency, CTR, spend, or any other ad metric.
- Creating, editing, launching, or pausing ads, campaigns, ad sets, or creatives.
- Slack replies, Buffer scheduling, and Zapier, Make, or n8n scenarios.
- Drive, Slides, Linear, Airtable, Webflow, WordPress, and Framer handoffs
  (use those guides).
- Legal approval of claims, prices, or offers printed on the image.
- GET https://brandiseer.com/api/v1/usage (browser session only).

Prompt rewriter

Use this when a brief arrives as messy notes. It does not call Brandiseer. It only cleans text before you put it in prompt. The word list is a starting filter, not an official dictionary. If a phrase still describes colour, type, mood, or look, delete it by hand. 4:5 and 1.91:1 are absent on purpose. They are not Brandiseer ratios.

Copy-ready
// Local rewriter for a Cursor or Cowork helper script.
// Keeps subject, layout, composition, and on-image text.
// Strips colour, type, mood, and visual-style language.

const STYLE_WORDS =
  /\b(colou?rs?|palette|hex|fonts?|typefaces?|typography|serif|sans-serif|moods?|vibes?|aesthetics?|minimalist|luxury|playful|cinematic|pastel|neon|gradients?|moody|elegant|premium|on-brand)\b/gi;

const SLOT_TO_RATIO = {
  feed: "1:1",
  "square feed": "1:1",
  square: "1:1",
  "1:1": "1:1",
  story: "9:16",
  stories: "9:16",
  reel: "9:16",
  reels: "9:16",
  "story reel": "9:16",
  "stories reels": "9:16",
  vertical: "9:16",
  portrait: "9:16",
  "9:16": "9:16",
  landscape: "16:9",
  display: "16:9",
  banner: "16:9",
  "landscape display": "16:9",
  "16:9": "16:9",
  "4:3": "4:3",
};

function rewriteBrandiseerPrompt(input) {
  const headline = String(input.headline || "").trim();
  const subject = String(input.subject || input.brief || "").trim();
  const slotKey = String(input.slot || input.crop || "").trim().toLowerCase();
  const aspectRatio = SLOT_TO_RATIO[slotKey] || "";

  let prompt = [subject, headline ? `On-image text: "${headline}".` : ""]
    .filter(Boolean)
    .join(" ");

  prompt = prompt
    .replace(/#[0-9a-f]{3,8}\b/gi, " ")
    .replace(STYLE_WORDS, " ")
    .replace(/\s+/g, " ")
    .trim();

  return {
    prompt,
    aspectRatio,
    needsSubject: prompt.length < 12 || !aspectRatio,
  };
}

If needsSubject is true, ask the human for a subject and a placement. Do not POST. A seasonal or offer variant is not its own key. Pass the placement it refreshes (square feed, story, or landscape display) and put only a human-supplied line in headline. If the human asked for 4:5 or 1.91:1, do not invent a ratio. Ask, then use 9:16 or 16:9 and say the person will crop. Use 4:3 only when the human names that frame.

Add-ons

Add these after the feed-image smoke test passes. They do not change Brandiseer's image contract, and they do not give Brandiseer an ads sync.

Approval before anything launches

After imageUrl is in the image library, a named reviewer checks the still. Until that happens, do not launch. Brandiseer does not approve legal claims, prices, or offers. Ad review policies stay with Meta or Google. Brandiseer does not know those policies and does not submit an ad for review.

One brand per client account

Keep a table: Meta ad account id or Google Ads customer id, secret name, and bds_c_.... Require a named account on every library write when more than one client exists. If the name misses, stop and list the clients you configured. Confirm Brand IDs with GET /api/v1/brands. Never fall through to another client's Brand ID or another account's token.

Credit soft-limit

When credits is under a threshold you choose (for example 40), switch new ad images to mode: fast and resolution: 1K, or skip them. Fast at 1K costs 4 credits. An explicit "run anyway" from the human can override the skip. The threshold is yours, not a Brandiseer default.

Placement log

Keep a short note next to the work: account id, placement, variant, brandId, mode, aspectRatio, resolution, imageUrl, and whether a person uploaded it, a Meta hash came back, or a Google Ads resource name came back. Brandiseer does not write this log. Meta and Google Ads do not send it back to Brandiseer.

Handoff to the sibling guides

Do not embed a Slides deck, a Linear issue, an Airtable base, a Buffer schedule, a Slack desk, an always-on HTTP scenario, Webflow, WordPress, or Framer inside this ad creative guide.

Optional motion (not the refresh MVP)

Video is image-to-video only. Generate the still first, then send its public imageUrl to POST https://brandiseer.com/api/v2.1/video/generate. Poll GET https://brandiseer.com/api/v2.1/video/jobs/:jobId. Video jobs use status completed and a videoUrl, which is a different contract from image jobs (done and imageUrl). Read guide/video for tier, duration, and resolution before you enable this. Video credits are per second and are not the still table below. A video failure does not undo the still. An ad can hold that video only after a person uploads it in the ad platform. This guide does not document a video-ad create call. Leave motion off unless the brief explicitly asks to animate.

Limits & FAQ

Does Brandiseer create or launch the ad?

No. Brandiseer returns imageUrl. A person downloads that file and uploads it in Meta Ads Manager or Google Ads, then builds or swaps the ad and launches the test. An agent with the advertiser's own credentials can upload the bytes into the image library only. None of those paths create, edit, launch, or pause an ad, and none of them sync the ad account back to Brandiseer.

Is there a Brandiseer app for Meta or Google Ads?

No. There is no Brandiseer Meta app and no Brandiseer Google Ads app in this guide. Do not look for a native "send to Ads Manager" button on the Brandiseer side.

Do I need an ads MCP?

No. This guide uses the Ads Manager or Google Ads UI, or the documented image-library calls with the advertiser's own credentials. Do not invent an ads MCP. Brandiseer still only returns the still.

Can the agent read frequency or CTR?

No. Spotting fatigue is the person, in their own Ads Manager or Google Ads reporting, or by pasting numbers into the brief. Brandiseer does not read ad performance. This guide does not document an insights or reporting call.

Which Meta call is in this guide?

Only the image-library upload confirmed on Meta's ad account ad images reference:

  • POST https://graph.facebook.com/v25.0/act_{ad_account_id}/adimages
  • Parameter bytes: the image file as a base64 string
  • The return struct includes hash, url, url_128, url_256, url_256_height, url_256_width, height, width, and name, under images
  • Error 100 invalid parameter, 200 permissions error, 190 invalid OAuth 2.0 access token, 80004 too many calls to this ad account, 368 the action was deemed abusive or is otherwise disallowed, 613 rate limit

copy_from is a different operation (copy an existing hash between ad accounts). This guide does not use it for a new file. This guide does not call ad creative, ad, ad set, or campaign endpoints. Docs: Ad account ad images.

Which Google Ads call is in this guide?

Only the image asset upload confirmed on Google's REST examples and asset docs:

  • POST https://googleads.googleapis.com/v25/customers/{customerId}/assets:mutate
  • Headers: Authorization: Bearer ACCESS_TOKEN, developer-token, and login-customer-id when a manager calls a client account
  • Body: operations[].create with type IMAGE, name, and imageAsset.data (base64 raw bytes)
  • The mutate result includes the new asset's resource name
  • OAuth scope: https://www.googleapis.com/auth/adwords

This guide does not link the asset and does not create or pause an ad. An uploaded image asset cannot be changed or removed programmatically. Docs: REST auth · REST examples · Working with assets.

Where do the keys live?

The Brandiseer key (bds_...), the Meta OAuth token, and the Google Ads developer token plus OAuth token live in the agent host's secret store. Never in an ad, a doc, a Slack message, a prompt you commit, or a workflow export in git. Those ad-platform credentials belong to the advertiser. Brandiseer does not store them. Rotate any secret if it leaks. Poll a Brandiseer job with the same Brandiseer key that submitted it.

What do stills cost?

Credits per still. Failures refund. Async submits deduct immediately and refund if the job fails.

Mode1K2K4K
Fast468
Design568
Pro6810

402 means not enough credits. Pricing context: brandiseer.com/pricing.

Why is the still off-brand?

Almost always because the prompt contained colours, fonts, mood, or visual style. Strip them and generate again. See guide/image.

Why does the crop look wrong in the placement?

Brandiseer aspect ratios are 1:1, 16:9, 9:16, and 4:3. Generate the square feed at 1:1, Stories and Reels at 9:16, and landscape display at 16:9. Brandiseer cannot emit 4:5 or 1.91:1. Crop those in the ad platform.

Instagram stream ads recommend 1:1 and also allow 4:5 and 1.91:1. Instagram Stories recommend 9:16. The minimum image width called out on the Instagram ads media requirements page is 600 px for Stories. If a Story image sits between 4:5 and 9:16 and you provide no crop spec, Instagram crops it to 4:5. See Media requirements.

Google landscape marketing images must be 1.91:1 (recommended 1200 by 628, minimum 600 by 314, maximum file size 5120 KB). Square marketing images must be 1:1 (recommended 1200 by 1200, minimum 300 by 300, same file cap). Linking a 16:9 file as a landscape marketing image returns ASPECT_RATIO_NOT_ALLOWED. That check happens when the asset is linked, not when it is uploaded. See Performance Max asset requirements.

How long can I poll?

About 10 minutes, then the Brandiseer job expires. Poll every 3 to 5 seconds. Stop on done or failed as well. Do not start a second job for the same variant while the first is still open, or you will pay twice.

Which generate URL should new ad images use?

POST /api/v2/generate when the agent host waits long enough. POST /api/v2/generate/async when it does not. Legacy POST /api/v1/generate remains for older callers and only supports Fast and Pro via proMode boolean.

Why did the Meta upload fail?

Check the error code on the adimages edge. 100 is an invalid parameter (the bytes value is the usual suspect). 190 is an invalid OAuth 2.0 access token. 200 is a permissions error, which means this token cannot upload to that ad account. 80004 means too many calls to this ad account. 613 is a rate limit. 368 means the action was deemed abusive or is otherwise disallowed. The path must be /act_{ad_account_id}/adimages with the numeric id. Do not tell the human the library updated when hash is missing.

Why did the Google Ads upload fail?

The call needs developer-token and Authorization: Bearer with scope https://www.googleapis.com/auth/adwords. Customer ids omit hyphens. A manager calling a client account also sends login-customer-id. imageAsset.data must be the base64 raw bytes, not imageUrl. Image asset names should be unique. An image asset cannot be edited in place after it exists. This guide does not treat a failed mutate as a stored asset.

Does a library upload launch a test?

No. A Meta hash and a Google Ads resource name sit in the image library. A person still builds or swaps the ad, submits it to the platform's ad review, and launches. Ad review policies stay with Meta or Google. Brandiseer does not submit the ad and does not know the review result.

Does the agent approve claims on the image?

No. If the still has a price, a discount, or a legal line, a person reads it before anything launches. The words must be a line the human supplied. Brandiseer does not review the claim.

Demo / motion

Motion brief only. This is not an embed, and there is no walkthrough URL yet.

Working title: Ad creative refresh Length: 45 to 75 seconds

Story beats:

  1. A person pastes a fatigue note and asks Cursor or Cowork for a square feed refresh with a layout-only brief
  2. The agent calls Brandiseer (MCP or REST v2) and shows an on-brand still
  3. imageUrl is downloaded and uploaded in Meta Ads Manager or Google Ads by a person
  4. Optional cut: a Meta adimages call returns a hash, and no ad is created
  5. A human launches a test only after the still looks right

On screen: the agent transcript with the prompt (no colour or mood words, no invented offer), one finished still, and the image sitting in the ad account library. Blur the Brandiseer API key and any Meta or Google credential. Do not show a fake video player in the guide.

Example flows

Flow A: One fatigued feed ad, uploaded by a person

The person has already seen frequency up and CTR down on one square feed ad, and they paste that note into the brief. The brief: "Square feed refresh. Product centred, full item in frame. Empty margin around it. No on-image text. No logo. 1:1. I will upload it myself."

The agent selects the default brandId, sets aspectRatio to 1:1, mode to design, resolution to 2K, and useLogo to false, and returns imageUrl. It does not open Ads Manager to confirm the fatigue. You download the file, upload it as a new ad image, then build or swap the ad and launch the test yourself. Brandiseer did not create the ad.

Flow B: Variants across four placements

The brief lists four placements: square feed (1:1), Stories or Reels (9:16), landscape display (16:9), and a seasonal variant that reuses the square feed ratio. Each placement asks for 3 variants. Each variant says what is physically in the frame. No variant adds a price. The agent generates 12 stills and labels them with placement and variant. You upload each file in the ad platform UI. Twelve Design 2K stills cost 72 credits if all succeed. Failures refund. Four variants on each of the four placements would be 16 stills and 96 credits. Do not start that larger set unless the human asked for 4.

Flow C: Seasonal refresh with a line the human supplied

The brief: "Seasonal refresh of the square feed. Same product on a table, one autumn leaf beside it. On-image text: Autumn hours. 1:1. No other words."

The agent keeps the line "Autumn hours" because the human wrote it, uses 1:1, and returns imageUrl. It does not add a year, a discount, or a second line. You upload it and decide whether that seasonal ad replaces the fatigued one. If the brief had said "seasonal" and had not supplied the words, the agent would generate with no on-image offer and would ask before printing one.

Flow D: Optional Meta image library upload

The ad account already exists. You have asked for a library upload, and the advertiser's Marketing API token is in the secret store. The brief names a 1:1 feed image and gives ad_account_id. The agent generates the still, downloads the bytes, and POSTs them as bytes to /act_{ad_account_id}/adimages. It returns the hash and stops. It does not create a creative or an ad. You use that hash later, or you ignore it and upload another way. If the call returns error 190 or 200, the agent says so and does not claim the library changed.

Flow E: Credit check before a placement set

Before Flow B, the agent calls brandiseer_check_credits or GET https://brandiseer.com/api/v1/credits and reads credits. Twelve Design 2K stills need 72 credits. If the balance is lower, it stops or switches the batch to fast at 1K (4 credits each) only if you asked for that fallback. GET /api/v1/usage is a browser session endpoint. Do not call it from the agent.

Flow F: Style-only brief rejected

The brief: "Make the ad feel premium and moody, and pause the old one."

The agent does not generate. It asks which placement, what is physically in the frame, whether any words must appear on the image, and whether the logo is on. It does not pause an ad. Colour, font, and mood stay out of the prompt. It also refuses a brief whose only subject is a style word, and it refuses to invent a sale price so the variants look different.

Related use cases

Links

ResourceURL
Brandiseerhttps://brandiseer.com
Developershttps://brandiseer.com/developers
API reference (guide/docs)https://brandiseer.com/guide/docs
Image prompt compatibilityhttps://brandiseer.com/guide/image
Video prompting (optional motion)https://brandiseer.com/guide/video
MCP endpoint (agent hosts)https://brandiseer.com/api/mcp
API keyshttps://brandiseer.com/settings/api
Pricing / creditshttps://brandiseer.com/pricing
Meta Ads Managerhttps://adsmanager.facebook.com
Meta: ad account ad imageshttps://developers.facebook.com/docs/marketing-api/reference/ad-account/adimages/
Meta: Instagram ads media requirementshttps://developers.facebook.com/docs/instagram/ads-api/reference/media-requirements/
Meta: Marketing API authorizationhttps://developers.facebook.com/docs/marketing-api/overview/authorization/
Google Adshttps://ads.google.com
Google Ads: REST authhttps://developers.google.com/google-ads/api/rest/auth
Google Ads: REST exampleshttps://developers.google.com/google-ads/api/rest/examples
Google Ads: working with assetshttps://developers.google.com/google-ads/api/docs/assets/working-with-assets
Google Ads: Performance Max asset requirementshttps://developers.google.com/google-ads/api/performance-max/asset-requirements
Google Ads: ImageAssethttps://developers.google.com/google-ads/api/reference/rpc/v25/ImageAsset
Google Ads API center (developer token)https://ads.google.com/aw/apicenter
Visual pack manifestassets/MANIFEST.md
Live: Drive & Slides deck visualshttps://blog.brandiseer.com/use-cases/drive-slides-deck-visuals
Live: Linear issue visualshttps://blog.brandiseer.com/use-cases/linear-issue-visuals
Live: Airtable record visualshttps://blog.brandiseer.com/use-cases/airtable-record-visuals
Live: Slack creative deskhttps://blog.brandiseer.com/use-cases/slack-creative-desk
Live: Social media automationhttps://blog.brandiseer.com/use-cases/social-media-automation
Live: Always-on creative automationhttps://blog.brandiseer.com/use-cases/always-on-creative-automation
Live: Webflow site visualshttps://blog.brandiseer.com/use-cases/webflow-site-visuals
Live: WordPress site visualshttps://blog.brandiseer.com/use-cases/wordpress-site-visuals
Live: Framer site visualshttps://blog.brandiseer.com/use-cases/framer-site-visuals
Sibling: Drive & Slides deck visualshttps://blog.brandiseer.com/use-cases/drive-slides-deck-visuals
Sibling: Linear issue visualshttps://blog.brandiseer.com/use-cases/linear-issue-visuals
Sibling: Airtable record visualshttps://blog.brandiseer.com/use-cases/airtable-record-visuals
Sibling: Always-on creative automationhttps://blog.brandiseer.com/use-cases/always-on-creative-automation
Sibling: Slack creative deskhttps://blog.brandiseer.com/use-cases/slack-creative-desk
Sibling: Social media automationhttps://blog.brandiseer.com/use-cases/social-media-automation
Sibling: Webflow site visualshttps://blog.brandiseer.com/use-cases/webflow-site-visuals
Sibling: WordPress site visualshttps://blog.brandiseer.com/use-cases/wordpress-site-visuals
Sibling: Framer site visualshttps://blog.brandiseer.com/use-cases/framer-site-visuals

Source

Public Use case README for an ad creative refresh. Brandiseer MCP and REST v2 image generation from Cursor or Claude Cowork, then a human downloads imageUrl and uploads it in Meta Ads Manager or Google Ads, or an agent with the advertiser's own credentials uploads the bytes into the ad account image library (Meta POST /act_{ad_account_id}/adimages, or Google Ads assets:mutate with an image asset). Aligned with guide/docs and guide/image (5 October 2026), with Meta's ad account ad images reference, and with Google Ads REST auth, the REST binary-asset example, and the asset upload docs. Brandiseer returns imageUrl only. It does not create, edit, launch, or pause ads or campaigns, does not read ad performance, and does not sync. There is no Brandiseer Meta app, no Brandiseer Google Ads app, and no ads MCP. Distinct from Drive and Slides deck visuals, Linear issue visuals, Airtable record visuals, Slack creative desk, Buffer organic scheduling, Zapier/Make/n8n always-on HTTP, Webflow site visuals, WordPress site visuals, and Framer site visuals.

API reference

Wiring reference for agents and HTTP modules. The sections above are the human path.

MCP (interactive stills in Cursor or Cowork)

Connect https://brandiseer.com/api/mcp with Authorization: Bearer and the API key. The only tools this guide uses are:

  • brandiseer_list_brands
  • brandiseer_check_credits
  • brandiseer_generate_image

Do not invent extra Brandiseer tool names. If the host needs explicit mode, aspectRatio, or async polling, use REST v2 below. MCP does not edit Meta or Google Ads. Do not invent an ads MCP.

REST (prefer v2 images)

Send X-API-Key: bds_... on every authenticated Brandiseer call. There is no official SDK. Any HTTP client the agent host can run is enough.

CallWhat you get
POST https://brandiseer.com/api/v2/generateSync still. 200 body { "imageUrl", "creditsUsed" }. Design mode often takes 40 to 70 seconds.
POST https://brandiseer.com/api/v2/generate/async202 body { "data": { "jobId" } } (ids look like bds_job_...). Credits are deducted when you submit.
GET https://brandiseer.com/api/v2/jobs/:jobIdPoll every 3 to 5 seconds with the same API key. data.status becomes done or failed. Jobs expire after about 10 minutes. Failures refund credits.
POST https://brandiseer.com/api/v1/generateLegacy only. proMode boolean. Fast and Pro only. Prefer v2.
GET https://brandiseer.com/api/v1/creditsJSON includes credits, the current balance for that key.
GET https://brandiseer.com/api/v1/brandsBrands for the key. Each brand id looks like bds_c_....
GET https://brandiseer.com/api/v1/health{ "status": "ok" }. No API key.

Image body fields: brandId, prompt, optional aspectRatio (1:1, 16:9, 9:16, 4:3), resolution (1K, 2K, 4K), mode (fast, design, or pro; default fast if you omit it), useLogo.

Sync status codes you should branch on: 200 success, 400 bad body, 401 bad key, 402 not enough credits, 404 brand not found, 500 server error.

Done job body: { "data": { "status": "done", "imageUrl", "creditsUsed", "referenceImage" } }. Hand data.imageUrl to the person, or download those bytes for a library upload. Failed job body: { "data": { "status": "failed", "error": { "code", "message" } } }.

Cursor and Cowork can wait on a sync Design call when the session allows it. If the HTTP client times out under about 60 seconds, use async and poll. Do not point Meta or Google Ads at the Brandiseer MCP URL.

Meta ad image upload (library only)

Send this only when the human asked for a library upload and the advertiser's own token is in the secret store. Brandiseer does not mint that token.

CallWhat you get
POST https://graph.facebook.com/v25.0/act_{ad_account_id}/adimagesCreates an ad image in that ad account's library. The documented file parameter is bytes (base64). The images node contains a struct with hash.

ad_account_id is the numeric id. The path includes the act_ prefix. The version segment v25.0 is the current version listed on the ad account ad images reference checked for this guide. If the advertiser's app is pinned to another version that same reference still documents, change only the version segment.

ParameterRule
bytesRequired for a new file. Base64 of the image bytes you downloaded from imageUrl. Not a remote URL.
copy_fromCopies an existing image from another ad account (source_account_id and hash). Out of scope for a new Brandiseer file.
access_tokenThe advertiser's own OAuth access token. Marketing API reference examples send it as a form field. Do not send the Brandiseer key here.

Return struct fields, from the adimages reference: hash, url, url_128, url_256, url_256_height, url_256_width, height, width, name. Read hash. The map key inside images is chosen by Meta. Do not assume it is your filename.

Error codes on this edge: 100 invalid parameter, 200 permissions error, 190 invalid OAuth 2.0 access token, 368 abusive or disallowed, 613 rate limit, 80004 too many calls to this ad account.

This guide does not document creating an ad creative from hash. The hash is the library id a person, or their own tooling, uses later.

Google Ads image asset upload (library only)

Send this only when the human asked for a library upload. You need the advertiser's developer token and OAuth access token. Brandiseer does not issue either.

HeaderRule
AuthorizationBearer ACCESS_TOKEN. Scope https://www.googleapis.com/auth/adwords.
developer-tokenRequired on every Google Ads API call. From a manager account at API center.
login-customer-idThe manager customer id, digits only, when a manager calls a client account. Omit it when the OAuth user is a direct user of the target client.
Content-Typeapplication/json
CallWhat you get
POST https://googleads.googleapis.com/v25/customers/{customerId}/assets:mutateCreates an image asset. {customerId} has no hyphens. The mutate result includes the new asset's resource name.

imageAsset.data is mutate-only raw bytes. In JSON, send standard base64 (padding is accepted; URL-safe base64 is also accepted on the REST examples page). Do not put imageUrl in data.

The REST examples page body sets name, type IMAGE, and imageAsset.data. The upload-image sample also sets fileSize, mimeType, and fullSize on the image asset. This guide does not treat those three as required, because the shorter REST example omits them.

Unique names are required for image assets. If you supply an existing name, Google creates a new name by appending a unique string. If an existing image asset has the same content and a different name, the new name is dropped silently. After upload, an image asset cannot be changed or removed programmatically.

This guide does not call a campaign, ad group, asset group, or ad mutate. The resource name is what a person, or their own tooling, uses later. A 16:9 upload can sit in the library and still fail a later link as a landscape marketing image, because that link expects 1.91:1.

Field mapping

Brandiseer generate body:

Incoming fieldAPIRule
Placement (square feed, Stories or Reels, landscape display, seasonal or offer)aspectRatioSquare feed: 1:1. Stories or Reels: 9:16. Landscape display: 16:9. Seasonal or offer: the placement's ratio. 4:5 and 1.91:1 are not sent. 4:3 only when the human names it.
headlineinside prompt onlyOn-image text and placement. Not a separate body field. Only a line the human supplied. Leave it out when the ad platform will hold the headline.
brandIdbrandIdbds_c_.... Required.
modemodefast, design, or pro. Omit and the API uses fast. Prefer design for these stills.
useLogouseLogotrue or false.
subject or briefpromptAfter the rewriter. If the cleaned text has no subject, do not call Brandiseer.
resolutionresolution1K, 2K, or 4K. Prefer 2K for these stills.

Library placement. The account below is whatever the human named. Do not invent it.

Incoming valueLibraryRule
PNG bytes downloaded from imageUrlMeta bytes, or Google imageAsset.dataBase64. Not the URL string.
Meta ad account idpath act_{ad_account_id}Numeric id. Required for a Meta upload.
Meta response hashimage library idStop here. Do not create a creative in this guide.
Google customer idpath customers/{customerId}Digits only. Required for a Google upload.
Google asset namecreate.nameUnique and descriptive.
Google mutate resource nameimage library idStop here. Do not link the asset in this guide.

Example JSON

Use this body for both Brandiseer sync and async. Only the URL and the response change.

Copy-ready
{
  "brandId": "bds_c_...",
  "prompt": "Square feed ad. Product centred, full item in frame. Empty margin around the subject. No on-image text.",
  "aspectRatio": "1:1",
  "resolution": "2K",
  "mode": "design",
  "useLogo": false
}

Sync: POST https://brandiseer.com/api/v2/generate. A Design 2K still costs 6 credits, so a success body looks like:

Copy-ready
{
  "imageUrl": "https://...",
  "creditsUsed": 6
}

Async: POST https://brandiseer.com/api/v2/generate/async. HTTP 202:

Copy-ready
{
  "data": {
    "jobId": "bds_job_..."
  }
}

Poll GET https://brandiseer.com/api/v2/jobs/bds_job_... with the same X-API-Key. When it finishes:

Copy-ready
{
  "data": {
    "status": "done",
    "imageUrl": "https://...",
    "creditsUsed": 6,
    "referenceImage": null
  }
}

When it fails (credits are refunded):

Copy-ready
{
  "data": {
    "status": "failed",
    "error": {
      "code": "...",
      "message": "..."
    }
  }
}

Ignore referenceImage for delivery. The ad account gets a file you downloaded from imageUrl.

Meta library upload. POST form fields to https://graph.facebook.com/v25.0/act_AD_ACCOUNT_ID/adimages. BYTES_BASE64 is the PNG you downloaded, not imageUrl.

Copy-ready
bytes=BYTES_BASE64
access_token=ADVERTISER_ACCESS_TOKEN

Read hash from the struct under images. The official return type is a map whose image struct includes hash, url, height, width, and name. Do not continue into an ad creative call.

Google Ads library upload. POST this JSON to https://googleads.googleapis.com/v25/customers/CUSTOMER_ID/assets:mutate with Authorization: Bearer ACCESS_TOKEN, developer-token, and Content-Type: application/json. Add login-customer-id when a manager is calling a client. DATA_BASE64 is the raw image, matching the REST examples page.

Copy-ready
{
  "operations": [
    {
      "create": {
        "name": "Square feed refresh 1",
        "type": "IMAGE",
        "imageAsset": {
          "data": "DATA_BASE64"
        }
      }
    }
  ]
}

A successful mutate includes the new asset's resource name. Do not chain a campaign or ad mutate onto this request.

Slot prompts that stay layout-only:

SlotaspectRatioPrompt
Square feed1:1Square feed ad. Product centred, full item in frame. Empty margin around the subject. No on-image text.
Stories or Reels9:16Vertical story frame. Subject in the middle band. Empty band along the top. Empty band along the bottom. No on-image text.
Landscape display16:9Landscape display frame. Subject left of centre. Empty right third. No on-image text.
Seasonal or offer variantsame as the placementSame frame as that placement. On-image text only when the human supplied the exact line. Otherwise no on-image text.
Named 4:3 frame4:34:3 frame. Single subject centred, full item in frame. Empty margin around the subject. No on-image text.

Run it with your brand

Connect the workflow to brand memory.

Save your visual identity in Brandiseer, then use MCP or the API to generate from the same brand across every supported workflow.